win32汇编语法

MASM程序第一部分是模式和源程序格式 
.386
.mode flat,stdcall
option casemap:none
带p的伪指令表示程序中可以使用特权指令

为了使用MMX指令,除了定义.586之外,还需要加上.mmx伪指令;

.model内存模式:tiny, small, medium,compact,large,huge,flat
tiny:用来建立.com文件,所有的代码、数据和堆栈都在64KB段内;
small:建立代码和数据分别用一个64KB段的.exe文件
medium:代码段可以使用多个64KB段,数据段只有一个64KB段;
compact:代码段只有一个64KB段,数据段可以使用多个64KB段;
large:代码和数据都可使用多个64KB段;
huge:数据段中一个数组可以超过64KB;
flat:WIN32程序使用的模式,代码段和数据段共同使用一个4GB段;

option casemap:none:定义程序中变量和子程序名是否对大小写敏感;


段的定义
.stack    ;堆栈段的大小
.data    ;一些初始化的变量定义
.data?    ;一些未初始化的变量定义
.const    ;一些常量定义
.code     ;代码定义

.data .data? .const段都是数据段。.code是代码段;系统为程序分配一个向下扩展的、足够大的段作为堆栈段,所以.stack段
定义会被忽略;

.data段数据值在程序装载完成后存入内存中;.data段一般存放在可执行文件的_DATA节区内;
.data?段不会增大.exe文件的大小;
.const段中的变量只可读,进行写操作直接报错;

.code段是默认是只读的,代码段的属性有可执行文件的PE头部中的属性位决定;代码段一般放在_TEXT节区中的;

.stack:可读写并可执行
----------------------------------------------------------------------------------------------------------

程序结束和程序入口:
程序员可指定从代码段的任何位置开始执行,这个位置由程序最后语句end语句决定;

WIN32汇编注释符(;)换行符(\);

----------------------------------------------------------------------------------------------------------

调用API:
    (1)CALL printString, addr szHello
    (2)使用invoke语句:
        invoke     函数名 , 参数1, 参数2
        invoke MessageBox,NULL, offset szText, offset szCaption, MB_OK 
        对于无参数的函数,既可以使用call,也可以使用invoke;
    (3)API返回值:
        返回值存放在eax寄存器中或者参数中提供的一个缓冲区地址;
        
    include语句:
        include     user32.inc 
        
    导入库:只包含函数的定位信息和参数数目等简单信息,这种库文件称作导入库,一个DLL对应一个导入库;
        如User32.dll 对应的导入库是User32.lib;
        需要告诉链接程序使用哪个导入库,使用
        includelib <导入库文件名>
        
----------------------------------------------------------------------------------------------------------
    标号和变量的命名规范:
        可以用字母、数字、下划线以及符号@、$和?。
    标号:用来表示跳转的目的地;标号既可以定义在目的指令同一行的头部,也可以在前独立一行定义,格式如下:
        标号名:        目标指令        ;方法1
        标号名::    目标指令        ;方法2    从一个子程序跳到另一个子程序的标号时使用,此时标号的作用域时整个程序;
        
----------------------------------------------------------------------------------------------------------
    全局变量:
        全局变量的定义:
            定义在.data或者.data?段内,语法如下:
                变量名        类型        初始值1,初始值2
                变量名        类型        重复数量 dup (初始值1,初始值2)
            类型:                缩写            长度(字节)
            byte                db                1
            word                dw                2
            dword                dd                4
            fword                df                6
            qword                dq                8
            tbyte                dt                10
            sbyte                                1                ;有符号字节
            sword                                2                
            sdword                                4
            Real4                                4
            Real8                                8    
            Real10                                10
        类型缩写只有在定义变量时才可用;
        byte类型变量定义中,引号定义字符串和数值定义可混用;
        
    局部变量:
        局部变量的作用域时单个子程序,在进入子程序的时候,通过修改堆栈指针esp来预留出需要的空间,在用
        ret指令返回主程序之前,通过恢复esp丢弃这些空间,这些变量就随之无效了。
        缺点是无法为定义含有初始值的变量;对局部变量的初始化一般在子程序中由
        指令完成。
        MASM用local伪指令提供对局部变量的支持。
        local         变量名    :类型, 变量2    :类型
            local     loc[1024]:byte            ;定义1024字节的局部变量loc
            
        -------子程序定义案例:
            TestProc     proc
                    local     @loc1:dword,@loc2:word
                    local    @loc3:byte

                    mov eax,@loc1 
                    mov ax, @loc2 
                    mov al, @loc3 
                    
                    ret 
            TestProc endp
        -------------------------------------------
        转换后的汇编代码如下:
            push     ebp                ;把返回的地址压入栈中,
            mov        ebp,     esp        ;转到子程序运行;
            add     esp,     FFFFFFF8    ;预留8字节的空间;
            mov     eax,     dword ptr [ebp-04]
            mov        ax,        word ptr [ebp-06]
            mov     al,        byte ptr [ebp-07]
            leave 
            ret
        ebp寄存器也是以堆栈段为默认数据段;
        局部变量一定要初始化,
        
    数据结构:
        汇编数据结构定义如下:
            结构名    struct 
                字段1        类型            ?
                字段2        类型            ?
            结构名   ends
            
        案例:
            WINCLASS struct 
                style         DOWRD         ?
                lpfnWndProc    DWORD        ?
                cbClsExtra    DWORD        ?
                hInstance    DWORD        ?
                hIcon        DWORD        ?
                hCursor        DWORD        ?
                hbrBackground    DWORD     ?
                lpszMenuName    DWORD    ?
                lpszClassName    DWORD    ?
            WINCLASS ends
            
            stWndClass WINCLASS         <1,1,1,1,1,1,1,1,1,1>
        使用结构中的字段用法 
            mov eax     stWndClass.lpfnWndProc        
        实际使用中,常使用指针存取数据结构,如果使用esi寄存器做指针寻址,
        mov esi, offset stWndClass
        mov eax,  [esi + WNDCLASS.lpfnWndProc]
        MASM还提供一个用法,使用assume伪指令将寄存器预先定义为结构指针,再进行操作:
            mov     esi, offset stWinClass 
            assume  esi:ptr WNDCLASS
            mov     eax, [esi].lpfnWndProc 
            assume  esi:nothing
        
        数据结构支持嵌套,
            NEW_WNDCLASS     struct 
                dwOptiond        dword        ?
                oldWndClass        WNDCLASS     <>
            NEW_WNDCLASS     ends
    
        
    
    


 

猜你喜欢

转载自blog.csdn.net/weixin_30961725/article/details/82467660
今日推荐