2014-05-01 53 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