【问题标题】:how do I call a external function in assembler?如何在汇编程序中调用外部函数?
【发布时间】:2017-01-18 04:08:38
【问题描述】:

我曾尝试在汇编代码中使用外部函数:

        .section    .rodata
    .LC0:
        .string "My number is: %lld"
        .text
        .globl  start
    start:
        pushq   %rbp
        movq    %rsp, %rbp
        subq    $16, %rsp
        movq    $12345, -8(%rbp)
        movq    -8(%rbp), %rax
        movq    %rax, %rsi
        movl    $.LC0, %edi
        movl    $0, %eax

        call    printf   # my external function

        # exit-syscall
        mov $1, %eax
        mov $0, %ebx
        int $0x80

我组装并链接到:

as -o myObjfile.o mySourcefile.s
ld -e start -o myProgram -lc myObjfile.o

可执行文件已构建,但无法运行,这是什么问题?

【问题讨论】:

  • 你得到什么错误信息?
  • 顺便说一句,使用编译器输出作为起点通常是好的,但您应该使用 optimize 编译器输出。使用gcc -O3 -S。并在 64 位代码中使用 64 位 ABI(syscall 指令而不是 int $0x80)。 args 的系统调用号和寄存器也不同。有关文档,请参阅 x86 tag wiki。另请参阅this answer about building code that defines _start instead of main, but still links libc
  • 由于您已经链接到 C 库,我建议也只使用 C 运行时。将 start 更改为 main ,而不是 int 0x80 (或系统调用)做 mov %rbp, %rsp pop %rbp ret 。在这种情况下,ret 将返回到 C 运行时干净地退出进程并刷新输出缓冲区。您可以使用 GCC 编译/组装 gcc -o myProgram mySourcefile.s
  • 或者,如果您愿意,您可以使用as -o myObjfile.o mySourcefile.s gcc -o myProgram myObjfile.o 拆分组装和链接(使用 GCC)让 GCC 进行链接将适当的参数传递给链接器,包括适当的动态链接器对象。
  • 我已经这样做了,现在可执行文件是可调用的。但是现在似乎不再调用 prinf 函数了。我没有看到它的消息。

标签: linux assembly hyperlink ld libc


【解决方案1】:

如果我理解正确,如果您要调用的函数在 C 库中,您可以将其声明为外部函数。

    .section    .rodata
.LC0:
    .string "My number is: %lld"
    .text
    .extern printf    #declaring  the external function
    .globl  start
start:
    pushq   %rbp
    movq    %rsp, %rbp
    subq    $16, %rsp
    movq    $12345, -8(%rbp)
    movq    -8(%rbp), %rax
    movq    %rax, %rsi
    movl    $.LC0, %edi
    movl    $0, %eax

    call    printf   # my external function

    # exit-syscall
    mov $1, %eax
    mov $0, %ebx
    int $0x80

如果这不起作用,请尝试将其与 stdlib.h 显式链接

【讨论】:

  • .extern 在 UNIX 汇编器中不需要。此外,OP 说他的代码可以构建,所以这不是问题。投反对票。
  • 是的,它使用 gcc/clang 构建正确。如果有人知道为什么使用as -o myObj.o mySrc.Sld -o myExe myObj.o -lc 的构建是不可执行的,那就太好了。
  • 好像只有链接过程失败。如果我像上面一样运行as 并使用`-nostartfiles` 标志将其输出与cc 链接,那么可执行文件就可以了。
猜你喜欢
  • 2020-08-11
  • 1970-01-01
  • 2016-10-24
  • 1970-01-01
  • 1970-01-01
  • 2018-11-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多