Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 如何在汇编程序中调用外部函数?_Linux_Assembly_Hyperlink_Ld_Libc - Fatal编程技术网

Linux 如何在汇编程序中调用外部函数?

Linux 如何在汇编程序中调用外部函数?,linux,assembly,hyperlink,ld,libc,Linux,Assembly,Hyperlink,Ld,Libc,我尝试在汇编代码中使用外部函数: .section .rodata .LC0: .string "My number is: %lld" .text .globl start start: pushq %rbp movq %rsp, %rbp subq $16, %rsp movq $12345, -8(%rbp)

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

        .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

可执行文件是构建的,但它没有运行,那么它有什么问题吗?

如果我理解正确,如果您要调用的函数在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

您会收到什么错误消息?顺便说一句,使用编译器输出作为起点通常是好的,但您应该使用优化编译器输出。使用
gcc-O3-S
。并在64位代码中使用64位ABI(即
syscall
指令,而不是
int$0x80
)。args的系统调用号和寄存器也不同。有关文档,请参见。另请参见。由于您已经针对C库进行了链接,我建议您也只使用C运行时。将
start
更改为
main
,而不是
int0x80
(或系统调用)执行
mov%rbp,%rsp
pop%rbp
ret
ret
将返回到C运行时,在这种情况下,将干净地退出进程并刷新输出缓冲区。您可以使用类似于
GCC-o myProgram mySourcefile.s的东西使用GCC编译/组装,或者如果您愿意,您可以(使用GCC)拆分组装和链接使用
as-o myObjfile.o mySourcefile.s
gcc-o myProgram myObjfile.o
让gcc进行链接将适当的参数传递给链接器,包括适当的动态链接器对象。我已经这样做了,现在可调用可执行文件。但是现在似乎不再调用prinf函数了;我没有看到它的消息。
.extern
在UNIX汇编程序中不需要。另外,OP说他的代码是构建的,所以这不是问题所在。向下投票。是的,它使用gcc/clang正确构建。如果有人知道为什么使用
as-o myObj.o mySrc.S
ld-o myExe myObj.o-lc
的构建不可执行,那就好了。似乎只有链接进程失败了。如果我像上面那样运行
,并使用`-nostartfiles`标志将其输出链接到
cc
,那么可执行文件就可以了。