2017-01-28 44 views
4

我想學習x86_64程序集,並使用GCC作爲我的彙編程序。我使用的確切命令是:退出系統調用的正確常量是多少?

gcc -nostdlib tapydn.S -D__ASSEMBLY__ 

我主要使用gcc作爲其預處理器。這裏是tapydn.S

.global _start 

#include <asm-generic/unistd.h> 

syscall=0x80 

.text 
_start: 
    movl $__NR_exit, %eax 
    movl $0x00, %ebx 
    int $syscall 

這會導致分段錯誤。我相信這個問題是以下行:

movl $__NR_exit, %eax 

我用__NR_exit因爲它比一些神奇的數字更具描述性的。但是,看來我的使用不正確。我相信這是因爲當我改變問題以下行,它運行良好的情況下:

movl $0x01, %eax 

而且備份的思想這條古道是usr/include/asm-generic/unistd.h內容:

#define __NR_exit 93 
__SYSCALL(__NR_exit, sys_exit) 

我預計__NR_exit的值爲1,而不是93!很顯然,我誤解了它的目的,並因此誤用了它的用法。據我所知,我很幸運與$0x01的情況下工作(很像C++中的未定義的行爲),所以我一直在挖...

接下來,我查找了sys_exit的定義。我找不到它。我試圖使用它無論如何如下(有和沒有前述$):

movl $sys_exit, %eax 

這不會鏈接:

/tmp/cc7tEUtC.o: In function `_start': 
(.text+0x1): undefined reference to `sys_exit' 
collect2: error: ld returned 1 exit status 

我的猜測是,它的系統庫中的一個象徵,由於我通過了-nostdlib GCC,我沒有鏈接它。如果可能的話,我想避免將這樣一個大型庫鏈接到一個符號。

響應於小丑的約混合32個和64位常數評論,我試圖使用值0x3C的建議:

movq $0x3C, %eax 
movq $0x00, %ebx 

這也導致段故障。我也嘗試了raxrbx換出eaxebx

movq $0x3C, %rax 
movq $0x00, %rbx 

段故障依然存在。

小丑則評論指出,我應該使用syscall而不是int $0x80

.global _start 

#include <asm-generic/unistd.h> 

.text 
_start: 
    movq $0x3C, %rax 
    movq $0x00, %rbx 
    syscall 

這工作,但我後來得知我應該使用rdi代替rbx按照系統V AMD64 ABI:

movq $0x00, %rdi 

這也工作正常,但仍然使用幻數0x3C系統調用號結束。

結束語,我的問題如下:

  • 什麼是__NR_exit正確使用?
  • 我應該用什麼來代替exit系統調用的幻數?
+0

您正在混合32位和64位常量(它們不相同)。其實你甚至使用asm-generic,這是完全無關的。 32位常量是'1',64位是'60'。 – Jester

+0

@Jester感謝您的幫助!不過,我對此有點困惑:我嘗試將值從'0x01'更改爲'0x3C',並再次出現分段錯誤。命令「file a.out」指出可執行文件是x86_64,我在這裏丟失了什麼? – OMGtechy

+0

64位模式實際上使用「syscall」指令,「int 0x80」是傳統的32位兼容性接口。 – Jester

回答

1

獲取系統調用號碼的正確頭文件是sys/syscall.h。常量被稱爲SYS_###,其中###是您感興趣的系統調用的名稱。__NR_###宏是實現細節,不應使用。作爲一個經驗法則,如果一個標識符以一個下劃線開始,那麼它不應該被使用,如果它以兩個字符開始,它肯定不會被使用。爭論進入rdi,rsi,rdx,r10, r8r9。下面是Linux的示例程序:

#include <sys/syscall.h> 

    .globl _start 
_start: 
    mov $SYS_exit,%eax 
    xor %edi,%edi 
    syscall 

這些約定大多可移植到其他類UNIX操作系統。

+0

在我的64位Ubuntu上,我發現文件是'/ usr/include/x86_64-linux-gnu/bits/syscall.h'。 – user2023370

+0

@ user2023370該文件包含在「sys/syscall.h」中。你不應該直接包含它。 – fuz

+0

此文件不存在。 – user2023370