探讨一下 printf 的处理过程
C代码:
#include<stdio.h>
main()
{
int x=10, y=20, z=30;
printf("%d %d %d\n",x=y=z, x=y==z, x==(y==z));
}
编译码:
图片附件: 游客没有浏览图片的权限,请
登录 或
注册
注释:
int x=10, y=20, z=30
MOV DWORD PTR SS:[ESP+1C],0A
; | x = 10
MOV DWORD PTR SS:[ESP+18],14
; | y = 20
MOV DWORD PTR SS:[ESP+14],1E
; | z = 30
x==(y==z) 结果 0
MOV EAX,DWORD PTR SS:[ESP+18]
; | EAX = y
CMP EAX,DWORD PTR SS:[ESP+14]
; | y==z
SETE AL
; | AL = (y==z)
MOVZX EAX,AL
; | EAX = (y==z)
CMP EAX,DWORD PTR SS:[ESP+1C]
; | x==(y==z)
SETE AL
; | AL = x==(y==z)
MOVZX EAX,AL
; | EAX = x==(y==z)
x=y==z 结果 x=0
MOV EDX,DWORD PTR SS:[ESP+18]
; | EDX = y
CMP EDX,DWORD PTR SS:[ESP+14]
; | y==z
SETE DL
; | DL = y==z
MOVZX EDX,DL
; | EDX = y==z
MOV DWORD PTR SS:[ESP+1C],EDX
; | x = (y==z),此时x=0
x=y=z 结果 x=30
MOV EDX,DWORD PTR SS:[ESP+14]
; | EDX = z
MOV DWORD PTR SS:[ESP+18],EDX
; | y = z
MOV EDX,DWORD PTR SS:[ESP+18]
; | EDX = y
MOV DWORD PTR SS:[ESP+1C],EDX
; | x = y,注意!这时x被修改为30
printf("%d %d %d\n",x=y=z, x=y==z, x==(y==z));
结果 printf("%d %d %d\n", x, x, 0);
MOV DWORD PTR SS:[ESP+C],EAX
; | printf第4个参数x==(y==z)结果 0
MOV EAX,DWORD PTR SS:[ESP+1C]
; | EAX = x
MOV DWORD PTR SS:[ESP+8],EAX
; | printf第3个参数x 结果 30
MOV EAX,DWORD PTR SS:[ESP+1C]
; | EAX = x
MOV DWORD PTR SS:[ESP+4],EAX
; | printf第2个参数x 结果 30
MOV DWORD PTR SS:[ESP],test.00404000 ; | ASCII "%d %d %d", printf第1个参数 "%d %d %d"
CALL <JMP.&msvcrt.printf>
; | 执行printf()
释放分配的内存返回
LEAVE
RETN
可见 printf() 是从右到左处理各个输入参数。