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

发布于 2024-11-16 21:36:22 字数 877 浏览 3 评论 0原文

我在让我在 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。提前致谢 :)

I've been having problems getting even the simplest of assembly programs that I write on Linux to run on my FreeBSD machine. Here's the offending code (I'm trying to keep this as simple as possible):

#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

The Linux machine returns the expected resulted which is sixty, whereas the FreeBSD machine consistently returns 164 for the return code. Does anybody know why this is? If so, can you please explain to me what is happening? Also, I should mention that they are both indeed running x86 CPUs. Thanks in advance :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

昔梦 2024-11-23 21:36:22

请参阅 FreeBSD 开发人员手册,你需要这样做:

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

因为:

  1. 只有系统调用向量通过寄存器%eax传递,所有参数都在堆栈上,
  2. FreeBSD默认系统调用需要在堆栈上有一个额外的字,这将是用于内联使用 int $0x80 的虚拟,但返回地址,您可以通过调用 kernel_entry 蹦床进行系统调用(然后可以执行 int $0x80; ret< /代码>)。

如果您想使用 Linux 约定(regs 中的某些系统调用参数,在手册中称为“替代调用约定”),则必须对可执行文件进行标记,以便系统知道您正在使用 Linux 风格的系统调用。

Refer to the FreeBSD Developer's handbook, and you need to do:

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

because:

  1. only the system call vector is passed via register %eax, all arguments are on the stack
  2. the FreeBSD default syscall expects an additional word on the stack, which would be a dummy for inlined uses of int $0x80 but a return address where you do a syscall via a call kernel_entry trampoline (that then can do int $0x80; ret).

If you want to use the Linux convention (some syscall args in regs, called "Alternative Calling convention" in the manual), you have to brand the executable so that the system knows you're using Linux-style syscalls.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文