我正在解决一个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
现在,当我只是将read_stdin
部分中所有的eax
替换为ebx
、ecx
或edx
时,二进制文件变得更大了:
$ wc -c main
268 main
当比较目标文件的大小时,差异更大(480比496字节)。eax
寄存器有什么特别之处导致出现这种情况?即使指定了-O0
,NASM是否进行了某种优化?
-Os
。 - phuclvld
中,您还需要使用-n
选项来避免将节对齐到页面边界。 - Peter Cordes