4

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 バイトと 496 バイト)。eaxこれが起こるレジスターの何が特別なのですか?NASM は指定されていますが、何らかの最適化を行っ-O0ていますか?

4

1 に答える 1