2016-09-27 58 views
1

我使用的是ubuntu64 + gas 我使用AT & T程序集,我試圖給一個'e'分配al寄存器,並將其編譯爲32位程序AT&T大會嘗試「movb」一個字符常量註冊,核心轉儲

$貓c2.s

.code32 
.globl _start 
_start: 
movb 'e',%al # Problem here!!!! 
mov $1,%eax 
mov $0,%ebx 
int $0x80 

$爲-g c2.s -o c2.o & & LD c2.o -o C2

$ C2

分段故障(SIGSEGV)

我用gdb調試C2,並發現它在崩潰MOVB 'E',%人。很奇怪,「movb」怎麼會崩潰?

然後我打開我的語法使用英特爾相同的內容:

$貓b2.s

.intel_syntax noprefix 
.code32 
.section .text 
.global _start 
_start: 
    mov al,'e' 
    mov eax,1 
    mov ebx,0 
    int 0x80 

爲$ -g b2.s -o b2.o & & LD B2。 Ø-o B2

$ B2

這時間,沒問題。但是爲什麼,我的AT & T組件有什麼問題?

+0

聽起來很奇怪,你可以再次組裝第一個例子,並使用'objdump -d file.o'來查看實際的操作碼嗎?對第二種情況做同樣的事情,並進行比較。一見鍾情,他們看起來和我完全一樣。 – Ped7g

+0

你不應該需要'.code32'指令。將'--32'傳遞給彙編程序以彙編32位代碼; '.code32'只會改變彙編器識別和彙編的內容,但不會使輸出成爲32位的目標文件。 – fuz

回答

3

沒有那麼有趣。 AS

400078: a0 65 00 00 00 b8 01 movabs 0x1b800000065,%al 
    40007f: 00 00 
    400081: 00 bb 00 00 00 00  add %bh,0x0(%rbx) 
    400087: cd 80     int $0x80 

明顯產生用於AT & T語法此目標代碼,位置0x1b800000065沒有被映射,但英特爾;

400078: b0 65     mov $0x65,%al 
    40007a: b8 01 00 00 00   mov $0x1,%eax 
    40007f: bb 00 00 00 00   mov $0x0,%ebx 
    400084: cd 80     int $0x80 

刪除AT &牛逼.code32,你會得到這一點。

400078: 8a 04 25 65 00 00 00 mov 0x65,%al 
    40007f: b8 01 00 00 00   mov $0x1,%eax 
    400084: bb 00 00 00 00   mov $0x0,%ebx 
    400089: cd 80     int $0x80 

注意它是如何將內存位置0x64的內容移動到AL中的。

movb $'e',%al 

修復了這個問題。無論如何,在64位系統上開發32位代碼可能會在某個時間點給你帶來麻煩,特別是當你開始處理堆棧時。