汇编中call printf参数压栈时错误理解
EAX, ECX,EDX,EBX均可以32bit,16bit,8bit訪問,如下所示:
<-------------------EAX------------------------>
|<----------------------|-----------|----------->|
?|<---------AX--------->|
?|<---AH--->|<---AL--->|
測(cè)試代碼如下:
1 .section .data 2 output: 3 .asciz "Value is:%x\n" 4 val: 5 .int 0 6 7 .section .text 8 .globl main 9 main: 10 nop 11 movl $0x12345678, %eax 12 movl $0, %ecx 13 movw %ax, %cx 14 pushw %cx 15 pushl $output 16 call printf 17 addl $6, %esp 18 19 movl $1, %eax 20 movl $0, %ebx 21 int $0x80我的電腦是小端格式(MSB存于高位),所以預(yù)期的輸出結(jié)果是:0x5678,但是我編譯執(zhí)行后結(jié)果是:0x2dec5678,前面多出了2個(gè)字節(jié),但是明明我壓棧的時(shí)候使用的pushw,原來是printf獲取參數(shù)時(shí)使用的是4字節(jié)長(zhǎng)度,所以雖然我壓入的只有2個(gè)字節(jié),但是它訪問時(shí)以4字節(jié)訪問。
將代碼修改:
1 .section .data 2 output: 3 .asciz "Value is:%x\n" 4 val: 5 .int 0 6 7 .section .text 8 .globl main 9 main: 10 nop 11 movl $0x12345678, %eax 12 movl %eax, %ecx 13 pushl %ecx 14 pushl $output 15 call printf 16 addl $8, %esp 17 18 movl $0, %ecx 19 movw %ax, %cx 20 pushl %ecx 21 pushl $output 22 call printf 23 addl $8, %esp 24 25 movl $1, %eax 26 movl $0, %ebx 27 int $0x80預(yù)期輸出:
Value is:12345678
Value is:5678
結(jié)果輸出:
Value is:12345678
Value is:12
? 起先還以為是將0x12345678的最高字節(jié)0x12傳送到cx里面了,覺得相當(dāng)怪異,明明使用的是movw,要錯(cuò)也是0x1234,分析了下,原來又是printf作怪,函數(shù)調(diào)用后,其返回值一般是存儲(chǔ)在eax里面來傳遞的,而第一個(gè)printf的輸出:Value is:12345678恰好有0x12,18個(gè)字符(含'\n'),所以代碼執(zhí)行完15行的call后,eax的值已被printf的返回值修改,而不是我預(yù)期的0x12345678。所以匯編里面調(diào)用庫(kù)函數(shù)時(shí),要特別注意某些特殊寄存器的特殊用途,特別是這些庫(kù)是由其他高級(jí)語言通過編譯工具生成的時(shí)候。
轉(zhuǎn)載于:https://www.cnblogs.com/thammer/p/4311621.html
總結(jié)
以上是生活随笔為你收集整理的汇编中call printf参数压栈时错误理解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Tabcontrol动态添加TabPag
- 下一篇: 硬盘分区表知识——详解硬盘MBR