我在 Linux 上编写的最简单的汇编程序在我的 FreeBSD 机器上运行时遇到了问题。这是有问题的代码(我尽量保持简单):
#counts to sixty
.section .data
.section .text
.global _start
_start:
movl $1, %ecx #move $1 into ecx
movl $1, %eax
start_loop:
addl %ecx, %eax #add ecx to eax
cmpl $60, %eax #compare $60 and eax...
je end_loop #if eax = 60 go to end_loop
cmpl $60, %eax #
jle start_loop #jump if eax is < $60...
jmp start_loop #...to start_loop
end_loop:
movl %eax, %ebx #move the value of eax into ebx because ebx holds
#the return value
movb $1, %al #Move $1 into eax (int 1 is the value for the
#exit() syscall
int $0x80
Linux 机器返回预期结果,即 60,而 FreeBSD 机器始终返回 164 作为返回码。有谁知道这是为什么?如果是这样,您能向我解释一下发生了什么吗?另外,我应该提到它们确实都在运行 x86 CPU。提前致谢:)
最佳答案
引用FreeBSD Developer's handbook ,你需要做的是:
push %eax
mov $1, %eax
push %eax
int $0x80
因为:
- 只有系统调用向量通过寄存器
%eax
传递,所有参数都在堆栈上 - FreeBSD 默认系统调用需要在堆栈上有一个额外的字,这将是
int $0x80
的内联使用的虚拟对象,但返回地址是您通过call kernel_entry 进行系统调用的位置
蹦床(然后可以执行int $0x80; ret
)。
如果你想使用 Linux 约定(regs 中的一些系统调用参数,在手册中称为“替代调用约定”),你必须标记可执行文件,以便系统知道你正在使用 Linux 风格的系统调用。
关于linux - FreeBSD 系统上简单汇编程序的虚假结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6448933/