2011-12-14 180 views
14

我目前在Linux上学习汇编语言。我一直在使用“从头开始编程”一书,所有例子都是32位的。我的操作系统是64位的,我一直试图在64位上做所有的例子。我有麻烦,但是:x86_64汇编Linux系统调用混淆

.section .data 

.section .text 
.global _start 
_start: 
movq $60, %rax 
movq $2, %rbx 
int $0x80 

这只是调用Linux退出系统调用或它应该。相反,它会导致一个SEG FAULT,而当我改为做这个时

.section .data 

.section .text 
.global _start 
_start: 
movq $1, %rax 
movq $2, %rbx 
int $0x80 

它的工作原理。很显然,问题是我转向%rax的价值。我在第二个例子中使用的价值$ 1是'从头开始编程',据说可以使用互联网上的多个来源说64位系统呼叫号码是60美元。 Reference 我在做什么错?另外还应该注意哪些其他问题以及我应该使用什么参考?以防万一你需要知道,我从第五章开始编程。

回答

15

您正在运行i386和x86_64之间的一个令人惊讶的区别:它们不使用相同的系统调用机制。正确的代码是:

movq $60, %rax 
movq $2, %rdi ; not %rbx! 
syscall 

中断0x80总是调用32位的系统调用。它用于允许32位应用程序在64位系统上运行。

为了学习的目的,您应该尽量正确地按照教程进行操作,而不是随时随地翻译为64位 - 您可能遇到的其他一些重大行为差异。一旦你熟悉i386,,然后,你可以单独拿起x86_64。

+0

我可能最终会这样做。感谢您的答复。 – 2011-12-14 19:32:33

+0

应该为第一个系统调用参数使用`%rdi`,而不是`%rbx`。 – 2011-12-14 20:18:56

10

请仔细阅读本What are the calling conventions for UNIX & Linux system calls on x86-64

,并注意使用int 0x80的系统调用在x64系统是一个古老的兼容层。您应该在x64系统上使用syscall指令。

您仍然可以使用这种旧方法,但需要在x86模式下编译二进制文件,请参阅编译器/汇编程序手册以获取详细信息。

+0

很高兴看到有人指出x86_64 Linux实际上使用`syscall`而不是`sysenter`!我写了一个[更长的答案来解释两者之间的混淆](// stackoverflow.com/a/31510342/20789)。 – 2015-07-20 06:56:55

4

i386和x86_64之间的很多变化,包括用于进入内核的指令和用于传送系统调用参数的寄存器。这里就相当于你的代码:

.section .data 

.section .text 
.global _start 
_start: 
movq $60, %rax 
movq $2, %rdi 
syscall 

this answer引用到一个相关的问题:

的系统调用号是在拱下/ 86 /包括/ ASM/unistd_64.h Linux源代码。系统调用号码在rax寄存器中传递。参数为rdi,rsi,rdx,r10,r8,r9。该调用通过“系统调用”指令进行调用。系统调用覆盖rcx寄存器。回报是rax。

2

如果检查/usr/include/asm/unistd_32.h退出相当于1/usr/include/asm/unistd_64.h出口相当于60

4

duskwuffanswer正确指出64位x86 Linux与32位Linux系统调用的机制不同。

然而,这个答案是不完整的和误导性的一对夫妇的原因:

由于pointed out in the commentsSYSENTER实际上并没有很多64位Linux系统 -namely 64位AMD系统工作。

这是一个公认混乱的情况。该gory details are here,但它归结为是这样的:

对于32位内核,SYSENTER/SYSEXIT是唯一兼容对

对于龙64位内核[AMD和英特尔CPU之间]模式下... SYSCALL/SYSRET是唯一兼容对[之间的AMD和英特尔CPU]

目前看来,在64位模式下英特尔 CPU上,你可以得到AWA y使用SYSENTER,因为它与SYSCALL的功能相同,但AMD系统并非如此。

底线:始终在64位x86系统上的Linux上使用SYSCALL。这正是x86-64 ABI实际指定的内容。 (更多细节见wiki answer。)