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位程序区别
网友评论