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
,那么可执行文件就可以了。