汇编开发(一):数据类型

1. 定义变量

1). 数据类型
类型 用法
BYTE 8位无符号整型
SBYTE 8位有符号整型
WORD 16位无符号整型
SWORD 16位有符号整型
DWORD 32位无符号整型
SDWORD 32位有符号整型
FWORD 48位整型(远程指针被保护的模式)
QWORD 64位整型
TBYTE 80位整型
REAL4 32位IEEE短实数
REAL8 64位IEEE长实数
REAL10 80位IEEE扩展实数
2). 格式

定义变量格式:

[name] directive initializer [,initializer]...
  • directive: 数据类型可以使用1). 数据类型中的, 也可使用下表中的数据指令
类型 用法
DB 8位整型
DW 16位整型
DD 32位整型或实数
DQ 64位整型或实数
DT 80位整型
  • initializer: 默认值
3). BYTE和SBYTE定义
.data               ; 定义变量区域
    COMMENT &
        定义BYTE和SBYTE数据
    &
    value1 BYTE 'A'     ; 字符变量
    value2 BYTE 0       ; 最小的无符号字节
    value3 BYTE 255     ; 最大的无符号字节
    value4 SBYTE -128   ; 最小的有符号字节
    value5 SBYTE +127   ; 最大的有符号字节
    value6 BYTE ?       ; 定义变量,但不赋初值
    value7 BYTE 10h     ; 定义字节变量,初值为16进制数据
    value8 DB 255       ; 定义一个8位的变量
    value9 BYTE 10, 20, 30, 40  ; 定义列表,假设10的内存地址为0000,则20的内存地址为0001
    value10 BYTE 10, 20, 30, 40 ; 多行定义列表
            BYTE 50, 60, 70, 80
            BYTE 90, 100, 110, 120
    value11 BYTE 10, 32, 41h, 00100010b     ; 定义列表,其中元素表示不一致
    value12 BYTE "good morning", 0      ; 定义字符串,使用双引号
    value13 BYTE 'good night', 0        ; 定义字符串,使用单引号
    value14 BYTE 'g', 'o', 'o', 'd'     ; 使用字符分割
    value15 BYTE "Welcome to the Encryption Demo program"   ; 定义字符串, 多行
            BYTE "created by Kip Irvine.", 0dh, 0ah         ; 其中0dh,0ah,代表CR/LF,即换行
    value16 BYTE "welcome to the Encryption Demo program "  ; 与value17等价
    value17 \                                               ; 使用\换行,下一行的内容表示接在当前行的后面
    BYTE "Welcome to the Encryption Demo program "
    ; DUP运算符
    value18 BYTE 20 DUP(0)      ; 定义20个字节,全部等于0
    value19 BYTE 20 DUP(?)      ; 定义20个字节,全部未初始化
    value20 BYTE 4 DUP("STACK") ; 定义20个字节,"STACK"循环填充,"STACKSTACKSTACKSTACK"
4). WORD和SWORD定义
.data               ; 定义变量区域
    COMMENT &
        定义WORD和SWORD数据
    &
    word1 WORD 65535        ; 最大的无符号值
    word2 SWORD -32768      ; 最小的符号值
    word3 WORD ?            ; 无符号值,未定义
    word4 DW 65535          ; 无符号
    word5 DW -32768         ; 有符号
    word6 WORD 1, 2, 3, 4, 5    ; 16位数组, 假设1所代表的地址为0000,那么2代表的地址为0002,因为每个值占用两个字节
    word7 WORD 5 DUP(?)     ; 定义5个未初始化的值
5). DWORD和SDWORD定义
.data               ; 定义变量区域
    COMMENT &
        定义DWORD和SDWORD数据
    &
    dword1 DWORD 12345678h      ; 无符号32位整数
    dword2 SDWORD -2147484648   ; 有符号32位整数
    dword3 DWORD 20 DUP(?)      ; 无符号数组,20位长度
    dword4 DD 12345678h         ; 无符号
    dword5 DD -2147484648       ; 有符号
    dword6 DWORD dword1         ; 将其他变量的值赋值给新定义的变量
    dword7 DWORD 1, 2, 3, 4, 5  ; 定义数组,假设1的地址为0000,则2的地址为0004,因为每个变量占4个字节
6). QWORD定义
.data               ; 定义变量区域
    COMMENT &
        定义TBYTE数据,每个数值占用8个字节
    &
    tbyte1 TBYTE 800000000000001234h    ; 有效
    tbyte2 TBYTE -1234  ; 无效
7). TBYPE定义
十进制值 存储字节
+1234 00 00 00 00 00 00 00 00 12 34
-1234 80 00 00 00 00 00 00 00 12 34
.data               ; 定义变量区域
    COMMENT &
        定义TBYTE数据,每个数值占用8个字节
    &
    quad1 TBYTE 800000000000001234h ; 有效
    quad2 TBYTE -1234   ; 无效
8). 浮点型定义
.data               ; 定义变量区域
    COMMENT &
        定义浮点型数据
    &
    real1 REAL4 -1.2        ; 定义浮点类型
    real2 REAL8 3.2E-260    ; 定义浮点类型
    real3 REAL10 4.6E+4096  ; 定义浮点类型
    real5REAL4 20 DUP(0.0) ; 定义数组
9). 代码与变量混合
.code
main PROC           ; 定义主函数开始位置
    mov eax, 10     ; 将10压入eax寄存器
    .data
    temp DWORD ?    ; 定义临时变量
    .code
    mov temp, eax   ; 将eax寄存器的值存入temp变量中

    INVOKE ExitProcess, 0   ; 退出程序
main ENDP           ; 函数结束位置, ENDP 之前的内容,要与PROC 
END main            ; 设置了函数的入口与出口

2. 常量

1). 与变量对比
用途 Constant Variable
是否使用内存控件
程序运行时是否可以改变
2). 当前位置计数器
.data
    selfPtr DWORD $         ; 当前位置计数器
3). '=' 指令
name = expression
  • name: 常量名

  • expression: 一般情况下为32位整型值

  • 计算数组或者字符串指针

    COMMENT &
        计算数组长度:使用$(当前位置地址)- list首地址
    &
    listByte BYTE 10, 20, 30, 40    ; 定义列表
    ListSizeByte = ($ - listByte)       ; 计算BYTE类型数组长度
    listString BYTE "This is a long string, containing"
               BYTE "any number of characters."
    listStringSize = ($ - listString) ; 计算字符串长度
    listWord WORD 1000h, 2000h, 3000h, 4000h
    listWordSize = ($ - listWord) / 2  ; 计算WORD类型数组长度,除以2是因为WORD类型占16位,即2个字节
    listDword DWORD 10000000h, 20000000h, 30000000h, 40000000h
    listDwordSize = ($ - listDword) / 4 ; 计算DWORD类型数组长度,除以4是因为DWORD类型占据32位,即4个字节

注:测试长度时,将对应的变量存入寄存器,查看寄存器的值即可。在动态调试时无法读取到数组长度对应的值。

    COUNT = 5       ; 常量
    mov al,COUNT    ; 将常量存入al
    mov eax, ListSizeByte ; 将列表长度存入eax寄存器
    mov eax, listStringSize ; 将列表长度存入eax寄存器
    mov eax, listWordSize ; 将列表长度存入eax寄存器
    mov eax, listDwordSize ; 将列表长度存入eax寄存器

注:可在代码中重新使用=设置同一个量的数值

4). EQU 指令
name EQU expression
name EQU symbol
name EQU <text>

name: 常量名
express: 必须是一个有效的整型表达式
symbol: 必须是一个已经存在的符号名
text: 任何文本都可以出现在括号内

使用:

pressKey EQU <"Press any key to continue...",0>
.data               ; 定义变量区域
    prompt BYTE pressKey

注:与'='不同,EQU定义的不能在代码中重新设置数值

5). TEXTEQU 指令
name TEXTEQU <text>
name TEXTEQU textmacro     ; 文本宏
name TEXTEQU %constExpr  ; 整型表达式

使用:

COMMENT &
    类似于宏定义
&
rowSize = 5
countSize TEXTEQU %(rowSize * 2)    ; TEXTEQU 表达式
move TEXTEQU <mov>                  ; 替换关键字
setupAL TEXTEQU <move al,count>     ; 替换指令

continueMsg TEXTEQU <"Do you wish to continue (Y/N)?">
.data
prompt1 BYTE continueMsg
6). 64位程序
ExitProcess PROTO   ; 这之前的配置已经不需要了,ExitProcess将参数取消了

.data               ; 定义变量区域
sum QWORD 0         ; DWORD更改为QWORD
.code
main PROC           ; 定义主函数开始位置
    mov rax, 5      ; eax寄存器变为rax
    add rax, 5
    mov sum, rax

    mov  ecx,0      ; 将ecx寄存器设置为0
    CALL ExitProcess   ; 退出程序, INVOKE被CALL替换
main ENDP               ; 函数结束位置, ENDP 之前的内容,要与PROC 
END                     ; 设置了函数的入口与出口,END后面不需要再加main了

注:请注意查看64位和32位程序区别

猜你喜欢

转载自blog.csdn.net/weixin_34077371/article/details/86956800