我正在开发x86汇编代码高尔夫拼图。我使用NASM组装源文件:
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 vs 496字节)。这种情况发生在eax
寄存器有什么特别之处? NASM是否正在进行某种优化,即使已指定-O0
?
答案 0 :(得分:8)
EAX是累加器寄存器。它具有用于所有九种基本操作(ADD,ADC,AND,CMP,OR,SBB,SUB,TEST和XOR)的特殊单字节操作码。此外,MOV指令具有一个单字节操作码,用于将数据从恒定存储器位置移入累加器。