我正在研究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
部与ebx
,ecx
或edx
,二进制得到较大的:
$ wc -c main
268 main
当比较目标文件的大小时,甚至更大(480对496字节)。 eax
寄存器有什么特别之处?即使已指定-O0
,NASM是否正在进行某种优化?
你看过二进制差异吗? – Devolus
当EAX(或有时是AX或AL)是使用的寄存器时,几个特定的指令组合确实可以被编码得更短。 –
如果要缩小体积,你应该使用'-Os'代替 –