我想學習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
這也導致段故障。我也嘗試了rax
和rbx
換出eax
和ebx
:
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
系統調用的幻數?
您正在混合32位和64位常量(它們不相同)。其實你甚至使用asm-generic,這是完全無關的。 32位常量是'1',64位是'60'。 – Jester
@Jester感謝您的幫助!不過,我對此有點困惑:我嘗試將值從'0x01'更改爲'0x3C',並再次出現分段錯誤。命令「file a.out」指出可執行文件是x86_64,我在這裏丟失了什麼? – OMGtechy
64位模式實際上使用「syscall」指令,「int 0x80」是傳統的32位兼容性接口。 – Jester