【发布时间】: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_startinstead of main, but still links libc。 -
由于您已经链接到 C 库,我建议也只使用 C 运行时。将
start更改为main,而不是int 0x80(或系统调用)做mov %rbp, %rsppop %rbpret。在这种情况下,ret将返回到 C 运行时干净地退出进程并刷新输出缓冲区。您可以使用 GCC 编译/组装gcc -o myProgram mySourcefile.s -
或者,如果您愿意,您可以使用
as -o myObjfile.o mySourcefile.sgcc -o myProgram myObjfile.o拆分组装和链接(使用 GCC)让 GCC 进行链接将适当的参数传递给链接器,包括适当的动态链接器对象。 -
我已经这样做了,现在可执行文件是可调用的。但是现在似乎不再调用 prinf 函数了。我没有看到它的消息。
标签: linux assembly hyperlink ld libc