首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在asm中将文件指针从c传递给调用

如何在asm中将文件指针从c传递给调用
EN

Stack Overflow用户
提问于 2019-04-27 23:47:36
回答 1查看 505关注 0票数 -1

我正在和nasm打交道,在没有问题地做了hello world之后,我想我应该试着做一些c集成。

我正在使用c打开一个文件,然后我想使用为打开的文件返回的指针来处理文本。然而,当我在rdi中使用指针调用fgetc时,我得到一个“没有这样的文件或目录”,后面跟着一个segfault。

我做错了什么?

代码语言:javascript
复制
int64_t asmFunc(FILE* a, char* b);

int main()
{
   int num;
   FILE *fptr;
   size_t line_buf_size = 0;
   char *ret = malloc(100);
   fptr = fopen("./test.txt","r");

   if(fptr == NULL)
   {
      printf("Error!");   
      exit(1);             
   }

   printf("%ld", asmFunc(fptr, ret));

   return 0;
}
代码语言:javascript
复制
global asmFunc

section .text

extern fgetc

asmFunc:
  call fgetc  ; segfault occurs here.
(...)
  ret
EN

回答 1

Stack Overflow用户

发布于 2019-04-27 23:50:28

您需要学习并遵循Linux x86-64 ABI规范中记录的calling conventions,特别是它的§3.2.3参数传递部分。因此,指针值fptr%rdi中,指针值ret%rsi中,您可能应该为asmFunc推送一个调用帧

另请阅读x86 calling conventions维基百科。

如果您能够在一些example.c文件中编写与asmFunc等效的C语言代码(甚至是简化的代码),我建议您使用gcc -O -fverbose-asm -Wall -S example.c编译它,并查看发出的example.s汇编文件以获取灵感。大多数情况下,这类函数的第一条机器指令不是call (而是称为function prologue的指令,它更改堆栈指针%esp并在call stack上分配一些调用帧)

例如,在我的Linux/Debian/x86-64操作系统上,安装了gcc-8。

代码语言:javascript
复制
void asmfunc(FILE* fil, char*s) {
   fputc ('\t', fil);
   fputs (s, fil);
   fputc ('\n', fil);
   fflush (fil);
}

被编译成:

代码语言:javascript
复制
    .text
    .globl  asmfunc
    .type   asmfunc, @function
asmfunc:
.LFB11:
    .cfi_startproc
    pushq   %rbp    #
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    pushq   %rbx    #
    .cfi_def_cfa_offset 24
    .cfi_offset 3, -24
    subq    $8, %rsp    #,
    .cfi_def_cfa_offset 32
    movq    %rdi, %rbx  # fil, fil
    movq    %rsi, %rbp  # s, s
# /tmp/example.c:4:    fputc ('\t', fil);
    movq    %rdi, %rsi  # fil,
    movl    $9, %edi    #,
    call    fputc@PLT   #
# /tmp/example.c:5:    fputs (s, fil);
    movq    %rbx, %rsi  # fil,
    movq    %rbp, %rdi  # s,
    call    fputs@PLT   #
# /tmp/example.c:6:    fputc ('\n', fil);
    movq    %rbx, %rsi  # fil,
    movl    $10, %edi   #,
    call    fputc@PLT   #
# /tmp/example.c:7:    fflush (fil);
    movq    %rbx, %rdi  # fil,
    call    fflush@PLT  #
# /tmp/example.c:8: }
    addq    $8, %rsp    #,
    .cfi_def_cfa_offset 24
    popq    %rbx    #
    .cfi_def_cfa_offset 16
    popq    %rbp    #
    .cfi_def_cfa_offset 8
    ret 
    .cfi_endproc
.LFE11:
    .size   asmfunc, .-asmfunc
    .ident  "GCC: (Debian 8.3.0-6) 8.3.0"

但是请注意,在某些情况下,GCC有能力(例如使用-O2)进行tail-call优化,并且可能会专门调用一些leaf-functions

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55882234

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档