Jeśli dowiem się, jak kompilator analizowany go, będę aktualizować ten, ale przynajmniej nie musi być bez zgadywania, jak to kompilowane:
objdump --disassemble /tmp/hello (edited):
080483c4 <main>:
80483c4: 55 push %ebp
80483c5: 89 e5 mov %esp,%ebp
80483c7: 83 e4 f0 and $0xfffffff0,%esp
80483ca: 83 ec 10 sub $0x10,%esp
80483cd: b8 a0 84 04 08 mov $0x80484a0,%eax
80483d2: 89 04 24 mov %eax,(%esp)
80483d5: e8 22 ff ff ff call 80482fc <[email protected]>
80483da: c9 leave
80483db: c3 ret
80483dc: 90 nop
80483dd: 90 nop
80483de: 90 nop
80483df: 90 nop
Od wykonywalnych Linux oparte są zwykle na 0x8048000 , adres argument printf jest przesunięcie 0x00004a0 od początku binarny:
xxd /tmp/hello | grep 00004a0
00004a0: 4865 6c6c 6f2c 2077 6f72 6c64 210a 0000 Hello, world!...
Tak, adres łańcucha jest wciśnięty, a printf jest wywołany z tego jednego arg. Nic magicznego na tym poziomie, więc wszystkie fajne rzeczy zostały wykonane przez gcc.
Wywołanie 'printf' z pewnością nie wpisuje się w żaden wcześniejszy kod startowy. –
@R ..: To był tylko domysł i najlepsze, co mogę zrobić. Gdzie indziej można go było wykonać? – casablanca
@R ..: Nieważne, masz rację, a ja odpowiedziałem na własne pytanie. :) – casablanca