首页
社区
课程
招聘
[旧帖] [原创](新手入门)eax和ax与格式说明符%d的匹配问题 0.00雪花
发表于: 2014-6-5 22:05 1595

[旧帖] [原创](新手入门)eax和ax与格式说明符%d的匹配问题 0.00雪花

2014-6-5 22:05
1595
罗云斌的书在Clock的五角星画时钟标记的地方卡住了,于是初衷是想试试一堆POINT如何初始化
和使用。没想到···学的不扎实,出了小错误竟然卡住了。就OD了一下。

    简单说,就是eax和ax与格式说明符%d的匹配问题,刚开始纳闷,弄明白就觉得自己好白痴!

下面是源代码:
                .386
                .model  flat, stdcall
                option  casemap:none
                
include         windows.inc
include         user32.inc
includelib      user32.lib
include         kernel32.inc
includelib      kernel32.lib

                .data?
lpPoint POINT   5 dup(<>)
szBuffer1       dd    1024 dup (?)
szBuffer2       dd    1024 dup (?)
szBuffer3       dd    1024 dup (?)

                .data
szFmt           db      'x = %d', 0dh, 0ah
                db      'y = %d', 0
szCaption       db      'Test', 0

                .code
start:
        xor     eax, eax
        xor     ebx, ebx
        mov     lpPoint[0].x, byte ptr 2
        mov     lpPoint[0].y, byte ptr 2
        mov     ax, word ptr lpPoint[0].x
        mov     bx, word ptr lpPoint[0].y

        invoke  wsprintf,offset szBuffer1, offset szFmt, eax, ebx

        xor     eax, eax
        xor     ebx, ebx
        mov     lpPoint[1].x, byte ptr 3
        mov     lpPoint[1].y, byte ptr 3
        mov     ax, word ptr lpPoint[1].x
        mov     bx, word ptr lpPoint[1].y

        invoke  wsprintf,offset szBuffer2, offset szFmt, dword ptr ax, dword ptr bx 

        xor     eax, eax
        xor     ebx, ebx
        mov     lpPoint[2].x, byte ptr 4
        mov     lpPoint[2].y, byte ptr 4
        mov     ax, word ptr lpPoint[2].x
        mov     bx, word ptr lpPoint[2].y

        invoke  wsprintf,offset szBuffer3, offset szFmt, eax, ebx

        invoke  MessageBox, NULL, offset szBuffer1, offset szCaption, MB_OK
        invoke  MessageBox, NULL, offset szBuffer2, offset szCaption, MB_OK
        invoke  MessageBox, NULL, offset szBuffer3, offset szCaption, MB_OK

        end     start

                         

下边是反汇编的新手入门简单分析:

00401000 >xor     eax, eax
00401002  xor     ebx, ebx
00401004  mov     dword ptr [403014], 2
0040100E  mov     dword ptr [403018], 2
00401018  mov     ax, word ptr [403014]
0040101E  mov     bx, word ptr [403018]
00401025  push    ebx                              ; /<%d>
00401026  push    eax                              ; |<%d>
00401027  push    00403000                         ; |Format = "x = %d",CR,LF,"y = %d"
0040102C  push    0040303C                         ; |s = eaxANDax.0040303C
00401031  call    <jmp.&user32.wsprintfA>          ; \wsprintfA
00401036  add     esp, 10
00401039  xor     eax, eax
0040103B  xor     ebx, ebx
0040103D  mov     dword ptr [403015], 3
00401047  mov     dword ptr [403019], 3
00401051  mov     ax, word ptr [403015]
00401057  mov     bx, word ptr [403019]

;问题就在这里
0040105E  push    0                                ;  这里0默认类型dword
00401060  push    bx
00401062  push    0                                ; /<%d> = 0
00401064  push    ax                               ; |<%d>

00401066  push    00403000                         ; |Format = "x = %d",CR,LF,"y = %d"
0040106B  push    0040403C                         ; |s = eaxANDax.0040403C
00401070  call    <jmp.&user32.wsprintfA>          ; \wsprintfA
00401075  add     esp, 10
00401078  xor     eax, eax
0040107A  xor     ebx, ebx
0040107C  mov     dword ptr [403016], 4
00401086  mov     dword ptr [40301A], 4
00401090  mov     ax, word ptr [403016]
00401096  mov     bx, word ptr [40301A]
0040109D  push    ebx                              ; /<%d>
0040109E  push    eax                              ; |<%d>
0040109F  push    00403000                         ; |Format = "x = %d",CR,LF,"y = %d"
004010A4  push    0040503C                         ; |s = eaxANDax.0040503C
004010A9  call    <jmp.&user32.wsprintfA>          ; \wsprintfA

;--------------------------------------------------------------------------------
这里,分析一下问题:

0040105E  push    0                                ;  这里0默认类型dword
00401060  push    bx
00401062  push    0                                ; /<%d> = 0
00401064  push    ax                               ; |<%d>

1.这里的0默认类型是dword的双字类型,先入栈:      
0012FFAA   00000000

(入门朋友注意:入栈时esp是向低地址移动)

2.然后push bx;这里bx是word类型,于是只是占2字节:(这里按照源程序给出的数据)
0012FFA8   00000003
0012FFAC   00000000      

3.然后push 0 ;这里同第一步,入栈一个双字类型数据: 
0012FFA4   00000000
0012FFA8   00000003
0012FFAC   00000000

4.然后push ax;同第二步,入栈一个字类型(2字节)数据:
0012FFA2   00000003
0012FFA6   00030000
0012FFAA   00000000
0012FFAE   00000000

    最终x = %d, y = %d,其中%d从内存中取dword的数据,于是x = 00000003H, y = 00030000H
这样就产生了结果给出的y = 196608(也就是十六进制的30000)

 注意地址的变化,对应的也就是变量的类型了。


      附注:多动动脑子!刚碰到这个问题什么思路都没有,思路太窄!如果想到C里边%d输出的是int型数据,而int型在32位系统中就是32位的双字节,唉···只好告诫和我一样的入门者,多思考,别钻牛角尖,拓展思维。多动脑,长寿!

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (1)
雪    币: 6
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
新手入门,多多关照~~~嘿嘿
2014-6-8 09:40
0
游客
登录 | 注册 方可回帖
返回
//