FreeBSD系统简单汇编程序的虚假结果

时间:2011-06-23 03:13:03

标签: linux assembly compatibility freebsd gas

我一直遇到问题,即使是我在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。在此先感谢:)

1 个答案:

答案 0 :(得分:2)

请参阅FreeBSD Developer's handbook,您需要执行以下操作:

push %eax
mov $1, %eax
push %eax
int $0x80

,因为:

  1. 只有系统调用向量通过寄存器%eax传递,所有参数都在堆栈上
  2. FreeBSD默认的系统调用期望在堆栈上有一个额外的单词,对于内联使用int $0x80而言是假的,但是返回地址是你通过call kernel_entry蹦床进行系统调用(然后可以做int $0x80; ret)。
  3. 如果你想使用Linux约定(regs中的一些系统调用args,在手册中称为“Alternative Calling convention”),你必须对可执行文件进行标记,以便系统知道你正在使用Linux风格的系统调用。