【win32汇编】 0x02 变量的定义和使用

    在汇编中,变量都是放在.data或者.data?中的,其中分为全局变量和局部变量。
    全局变量:
        .data
        wHour    dw ?    #未初始化的word类型
        wMinute    dw    10     #初始化为10的word类型
        word_Buffer    dw    100 dup(1,2)    #200个字
        szBuffer byte 1024 dup(?)    #1024字节的缓冲区
        szText    db    'Hello World'    #字符串11个字节
        szText    db    'Hello World',0dh,0ah,'Hello again',0dh,0ah,0    #0dh,0ah为换行符
        (.data?段中无法指定初始化值,默认初始值为0)
    局部变量
        简述:在进入子程序的时候,通过修改栈指针esp来留出需要的空间,在用ret返回的时候就通过恢复esp来丢弃这个空间
        local    loc1[1024]:byte    #定义了1024自己长的局部变量loc1
        local    loc2    #dword(默认)的局部变量
        local    loc3:WNDCLASS    #一个WNDCLASS的数据结构
    注:可以使用sizeof和lengthof来计算变量的长度
    例:
        szHello    db    'Hello',0dh,0ah
                db    'World',0
        sizeof szHello的值为7
        改为stlen来计算这个字符串长度
    变量是利用指针来操作的
        lea eax,[ebp-4] 计算出地址放到eax中
        但是在invoke伪指令参数用到局部变量的时候不能用lea指令,只能用addr来代替从而获得变量的地址
        但是,这里又会有莫名其妙的问题:
            invoke Test,eax,addr szHello
            这句会被翻译成:
            lea eax,[ebx-4]
            push eax
            push eax
            call Test
        所以说eax不能用在addr的前面
        
    下面还有一个例子是对局部变量的分析

    源代码:

 1         ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 2         ;数据段
 3         ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 4             .data
 5         szCaption     db '来自deadfish', 0
 6         szText         db 'Hello, win32 assembly lanuage', 0
 7 
 8         ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 9         ;代码段
10         ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
11             .code
12         start:
13             call TestPro
14             invoke MessageBox,NULL,offset szText,offset szCaption,MB_OK
15             invoke ExitProcess,NULL
16         ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
17         ;子程序
18         ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
19         TestPro    proc
20                 local @loc1:dword,@loc2:word
21                 local @loc3:byte
22                 ;总共定义了7个字节的局部变量
23                 mov eax,@loc1
24                 mov    ax,@loc2
25                 mov al,@loc3
26                 ret
27         TestPro endp

    反汇编之后:

 1         00401000 >/$  E8 1A000000   call 02_1.0040101F
 2         00401005  |.  6A 00         push 0x0                                 ; /Style = MB_OK|MB_APPLMODAL
 3         00401007  |.  68 00304000   push 02_1.00403000                       ; |Title = "来自deadfish"
 4         0040100C  |.  68 0D304000   push 02_1.0040300D                       ; |Text = "Hello, win32 assembly lanuage"
 5         00401011  |.  6A 00         push 0x0                                 ; |hOwner = NULL
 6         00401013  |.  E8 1A000000   call <jmp.&user32.MessageBoxA>           ; MessageBoxA
 7         00401018  |.  6A 00         push 0x0                                 ; /ExitCode = 0x0
 8         0040101A  .  E8 19000000   call <jmp.&kernel32.ExitProcess>         ; ExitProcess
 9         0040101F  /$  55            push ebp                                 ;保存ebp的值
10         00401020  |.  8BEC          mov ebp,esp                                 ;把esp的值保存到ebp中 所以ebp的值很重要,不能随意改动,否则在退出子程序的是会出错
11         00401022  |.  83C4 F8       add esp,-0x8                             ;从栈申请8字节的空间给局部变量
12         00401025  |.  8B45 FC       mov eax,[local.1]                         ;赋值    这里就是通过ebp来指向局部变量的
13         00401028  |.  66:8B45 FA    mov ax,word ptr ss:[ebp-0x6]
14         0040102C  |.  8A45 F9       mov al,byte ptr ss:[ebp-0x7]
15         0040102F  |.  C9            leave                                     ;完成恢复功能,这里相当于   mov esp,ebp          pop ebp
16         00401030  .  C3            retn    
17         00401031      CC            int3
18         00401032   $- FF25 08204000 jmp dword ptr ds:[<&user32.MessageBoxA>] ;  user32.MessageBoxA
19         00401038   .- FF25 00204000 jmp dword ptr ds:[<&kernel32.ExitProcess>;  kernel32.ExitProcess

     然后再变量中还有一个要注意的:
        .data
        bTest1 db 12h
        wTest1 dw 1234h
        dTest1 dd 12345678h
        ...
        .code
        ...
        mov al,bTest    ;al=12h
        mov ax,word ptr wTest1    ;ax = 3412h
        mov eax,dword ptr dTest1    ;eax = 78563412h
        这样在运行之后的现象是因为.data的东西是按照高数据高地址的(8086汇编中就可以知道了)
        要避免这种情况,用movzx代替mov即可

原文地址:https://www.cnblogs.com/driedfish/p/5414147.html