Nếu tôi tìm ra cách trình biên dịch phân tích nó, tôi sẽ cập nhật này, nhưng ít nhất cần phải có không phỏng đoán như thế nào nó được biên dịch:
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
Kể từ khi thực thi Linux dựa bình thường tại 0x8048000 , địa chỉ của đối số để printf là tại một bù đắp của 0x00004a0 từ khi bắt đầu nhị phân:
xxd /tmp/hello | grep 00004a0
00004a0: 4865 6c6c 6f2c 2077 6f72 6c64 210a 0000 Hello, world!...
Vì vậy, địa chỉ của chuỗi được đẩy, và printf được gọi với một arg. Không có gì huyền diệu ở cấp độ đó, vì vậy tất cả những thứ thú vị được thực hiện bởi gcc.
Nguồn
2010-11-11 04:41:52
Cuộc gọi đến 'printf' chắc chắn không đi vào bất kỳ mã khởi động trước' 'nào'. –
@R ..: Đó chỉ là phỏng đoán và điều tốt nhất tôi có thể thực hiện. Nơi nào khác nó có thể được thực hiện? – casablanca
@R ..: Đừng bận tâm, bạn đúng về điều đó và tôi đã trả lời câu hỏi của riêng tôi. :) – casablanca