2014-05-01 52 views
4

我正在研究x86彙編代碼高爾夫拼圖。我組裝使用NASM源文件:ASM空間優化:EAX vs EBX

nasm -f elf32 -O0 main.s 
ld -m elf_i386 -s -O0 -o main main.o 

使用-O0,所有的優化應該被關閉。目標是減少ELF二進制文件的大小。

在研究謎題的「參考實現」時,我偶然發現了一個奇怪的行爲。這是一個降低代碼示例:

section .text 
    global _start  ; Must be declared for linker 

_start:     ; Entry point for linker 

read_stdin: 
    add esp, 8  ; Ignore argc and argv[0] on stack 
    pop eax   ; Store pointer to 'argv[1]' into EAX 
    mov eax, [eax] ; Dereference pointer 
    and eax, 0xff  ; We only want the least significant byte 
    add eax, -0x30 ; Subtract ascii offset 

exit: 
    mov eax, 1  ; Syscall: sys_exit 
    mov ebx, 0  ; Exit code 0 
    int 0x80   ; Invoke syscall 

二進制是264個字節:

$ wc -c main 
264 main 

現在,當我簡單地取代的eax所有出現在read_stdin部與ebxecxedx,二進制得到較大的:

$ wc -c main 
268 main 

當比較目標文件的大小時,甚至更大(480對496字節)。 eax寄存器有什麼特別之處?即使已指定-O0,NASM是否正在進行某種優化?

+0

你看過二進制差異嗎? – Devolus

+4

當EAX(或有時是AX或AL)是使用的寄存器時,幾個特定的​​指令組合確實可以被編碼得更短。 –

+0

如果要縮小體積,你應該使用'-Os'代替 –

回答

7

EAX是累加器寄存器。它對所有九種基本操作(ADD,ADC,AND,CMP,OR,SBB,SUB,TEST和XOR)都有特殊的單字節操作碼。此外,MOV指令具有一個單字節操作碼,用於將數據從恆定存儲位置移入累加器。

The Art of Picking Intel Registers

+0

謝謝, 這就說得通了。我找到了一些有用的相關鏈接:http://www.swansontec.com/sregisters.html http://www.swansontec.com/sintel.html http://www.mathemainzel.info/files/x86asmref.html#添加 –

+0

更新爲引用,對不起。 – spudone