知识点
小知识
ptr 强制类型转换
lea 指令可以用来将一个内存地址直接赋给目的操作数,例如:
lea eax,[ebx+8] 就是将ebx+8这个值直接赋给eax
mov eax,[ebx+8]则是把内存地址为ebx+8处的数据赋给eax。
32 位 |
16 位 |
8 位(高) |
8 位(低) |
EAX |
AX |
AH |
AL |
EBX |
BX |
BH |
BL |
ECX |
CX |
CH |
CL |
EDX |
DX |
DH |
DL |
32 位 |
16 位 |
32 位 |
16 位 |
ESI |
SI |
EBP |
BP |
EDI |
DI |
ESP |
SP |
- 乘除指令默认使用EAX。它常常被称为扩展累加器(extended accumulator)寄存器。
- CPU 默认使用 ECX 为循环计数器。
- ESP 用于寻址堆栈(一种系统内存结构)数据。它极少用于一般算术运算和数据传输,通常被称为扩展堆栈指针(extended stack pointer)寄存器。
- ESI 和 EDI 用于高速存储器传输指令,有时也被称为扩展源变址(extended source index)寄存器和扩展目的变址(extended destination index)寄存器。
- 高级语言通过 EBP 来引用堆栈中的函数参数和局部变量。除了高级编程,它不用于一般算术运算和数据传输。它常常被称为扩展帧指针(extended frame pointer)寄存器。
- 进位标志位(CF),与目标位置相比,无符号算术运算结果太大时,设置该标志位。
- 溢出标志位(OF),与目标位置相比,有符号算术运算结果太大或太小时,设置该标志位。
- 符号标志位(SF),算术或逻辑操作产生负结果时,设置该标志位。
- 零标志位(ZF),算术或逻辑操作产生的结果为零时,设置该标志位。
- 辅助进位标志位(AC),算术操作在 8 位操作数中产生了位 3 向位 4 的进位时,设置该标志位。
- 奇偶校验标志位(PF),结果的最低有效字节包含偶数个 1 时,设置该标志位,否则,清除该标志位。一般情况下,如果数据有可能被修改或损坏时,该标志位用于进行 错误检测。
操作数大小 |
可用寄存器 |
8 位 |
AL、BL、CL、DL、DIL、SIL、BPL、SPL、R8L、R9L、R10L、R11L、R12L、R13L、R14L、R15L |
16 位 |
AX、BX、CX、DX、DI、SI、BP、SP、R8W、R9W、R10W、R11W、R12W、R13W、R14W、R15W |
32 位 |
EAX、EBX、ECX、EDX、EDI、ESI、EBP、ESP、R8D、R9D、R10D、R11D、R12D、R13D、R14D、R15D |
64 位 |
RAX、RBX、RCX、RDX、RDI、RSI、RBP、RSP、R8、R9、R10、R11、R12、R13、R14、R15 |
h |
十六进制 |
r |
编码实数 |
q/o |
八进制 |
t |
十进制(备用) |
d |
十进制 |
y |
二进制(备用) |
b |
二进制 |
|
|
1
2
3
4
5
6
7
|
26 ;十进制
26d ;十进制
11010011b ;二进制
42q ;八进制
42o ;八进制
1Ah ;十六进制
0A3h ;十六进制
|
运算符 |
名称 |
优先级 |
() |
圆括号 |
1 |
+,- |
一元加、减 |
2 |
*, / |
乘、除 |
3 |
MOD |
取模 |
3 |
+, - |
加、减 |
4 |
$ |
PARITY? |
DWORD |
STDCALL |
? |
PASCAL |
FAR |
SWORD |
@B |
QWORD |
FAR16 |
SYSCALL |
@F |
REAL4 |
FORTRAN |
TBYTE |
ADDR |
REAL8 |
FWORD |
VARARG |
BASIC |
REAL10 |
NEAR |
WORD |
BYTE |
SBYTE |
NEAR16 |
ZERO? |
C |
SDORD |
OVERFLOW? |
|
CARRY? |
SIGN? |
|
|
.DATA 伪指令进行标识:
.data
.CODE 伪指令标识的程序区段包含了可执行的指令:
.code
.STACK 伪指令标识的程序区段定义了运行时堆栈,并设置了其大小:
.stack 100h
指令
一条指令有四个组成部分:
- 标号(可选)
- 指令助记符(必需)
- 操作数(通常是必需的)
- 注释(可选)
不同部分的位置安排如下所示:
[label: ] mnemonic [operands] [;comment]
标号
数据标号
代码标号
1
2
3
4
|
target:
mov ax,bx
...
jmp target
|
指令助记符
助记符 |
说明 |
助记符 |
说明 |
MOV |
传送(分配)数值 |
MUL |
两个数值相乘 |
ADD |
两个数值相加 |
JMP |
跳转到一个新位置 |
SUB |
从一个数值中减去另一个数值 |
CALL |
调用一个子程序 |
操作数
示例 |
操作数类型 |
示例 |
操作数类型 |
96 |
整数常量 |
eax |
寄存器 |
2+4 |
整数表达式 |
count |
内存 |
STC 指令没有操作数:
stc ;进位标志位置 1
INC 指令有一个操作数:
inc eax ;EAX 加 1
MOV 指令有两个操作数:
mov count, ebx ;将 EBX 传送给变量 count
IMUL 指令有三个操作数,第一个是目的操作数,第二个和第三个是进行乘法的源操作数:
imul eax,ebx,5
注释
- 单行注释,用分号(;)开始。汇编器将忽略在同一行上分号之后的所有字符。
- 块注释,用 COMMENT 伪指令和一个用户定义的符号开始。汇编器将忽略其后所有的文本行,直到相同的用户定义符号出现为止。
1
2
3
4
|
COMMENT !
This line is a comment.
This line is also a comment.
!
|
NOP(空操作)指令
1
2
3
4
5
6
7
8
9
|
.data ;此为数据区
sum DWORD 0 ;定义名为sum的变量
.code ;此为代码区
main PROC
mov eax,5 ;将数字5送入而eax寄存器
add eax,6 ;eax寄存器加6
mox sum,eax
INVOKE ExitProcess,0 ;结束程序
main ENDP
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
; AddTwo.asm -两个 32 位整数相加
.386
.model flat,stdcall
.stack 4096
ExitProcess PROTO, dwExitCode:DWORD
.code
main PROC
mov eax,5 ;将数字5送入eax寄存器
add eax,6 ;eax寄存器加6
INVOKE ExitProcess,0
main ENDP
END main
|
- 第 3 行是 .386 伪指令,它表示这是一个 32 位程序,能访问 32 位寄存器和地址。
- 第 4 行选择了程序的内存模式(flat),并确定了子程序的调用规范(称为 stdcall)。其原因是 32 位 Windows 服务要求使用 stdcall 规范。
- 第 5 行为运行时堆栈保留了 4096 字节的存储空间,每个程序都必须有。
- 第 6 行声明了 ExitProcess 函数的原型,它是一个标准的 Windows 服务。原型包含了函数名、PROTO 关键字、一个逗号,以及一个输入参数列表。ExitProcess 的输入参数名称为 dwExitCode。
汇编伪指令回顾
CODE 的下一行声明程序的入口
ENDP 伪指令标记一个过程的结束。
main ENDP
END 伪指令标记一个程序的结束,并要引用程序入口:
END main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
; AddTwo.asm - adds two 32-bit integers.
; Chapter 3 example
.386
.model flat,stdcall
.stack 4096
ExitProcess PROTO,dwExitCode:DWORD
00000000 .code
00000000 main PROC
00000000 B8 00000005 mov eax, 5
00000005 83 C0 06 add eax,6
invoke ExitProcess,0
00000008 6A 00 push +000000000h
0000000A E8 00000000 E call ExitProcess
0000000F main ENDP
END main
|
数据类型以及数据定义详解
内部数据类型
类型 |
用法 |
BYTE |
8 位无符号整数,B 代表字节 |
SBYTE |
8 位有符号整数,S 代表有符号 |
WORD |
16 位无符号整数 |
SWORD |
16 位有符号整数 |
DWORD |
32 位无符号整数,D 代表双(字) |
SDWORD |
32 位有符号整数,SD 代表有符号双(字) |
FWORD |
48 位整数(保护模式中的远指针) |
QWORD |
64 位整数,Q 代表四(字) |
TBYTE |
80 位(10 字节)整数,T 代表 10 字节 |
REAL4 |
32 位(4 字节)IEEE 短实数 |
REAL8 |
64 位(8 字节)IEEE 长实数 |
REAL10 |
80 位(10 字节)IEEE 扩展实数 |
数据定义语句
数据定义语法如下所示:
[name] directive initializer [,initializer]…
下面是数据定义语句的一个例子:
伪指令 |
用法 |
伪指令 |
用法 |
DB |
8位整数 |
DQ |
64 位整数或实数 |
DW |
16 位整数 |
DT |
定义 80 位(10 字节)整数 |
DD |
32 位整数或实数 |
|
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
;AddTowSum.asm
.386
.model flat,stdcall
.stack 4096
ExitProcess PROTO, dwExitCode:DWORD
.data
sum DWORD 0
.code
main PROC
mov eax,5
add eax,6
mov sum,eax
INVOKE ExitProcess,0
main ENDP
END main
|
定义 BYTE 和 SBYTE 数据
1
2
3
4
5
6
7
8
9
|
value1 BYTE 'A' ;字符常量
value2 BYTE 0 ;最小无符号字节
value3 BYTE 255 ;最大无符号字节
value4 SBYTE -128 ;最小有符号字节
value5 SBYTE +127 ;最大有符号字节
value6 BYTE ? ;变量
val1 DB 255 ;无符号字节
val2 DB -128 ;有符号字节
|
多初始值
偏移量 |
数值 |
0000 |
10 |
0001 |
20 |
0002 |
30 |
0003 |
40 |
1
2
3
|
list BYTE 10,20,30,40
BYTE 50,60,70,80
BYTE 81,82,83,84
|
1
2
|
list1 BYTE 10, 32, 41h, 00100010b
list2 BYTE 0Ah, 20h, 'A', 22h
|
list1与list2不同进制,但值相同
定义字符串
1
2
|
greeting1 BYTE "Good afternoon",0
greeting2 BYTE 'Good night',0
|
0作为结束标记
1
2
3
4
|
greeting1 BYTE "Welcome to the Encryption Demo program "
BYTE "created by Kip Irvine.",0dh, 0ah
BYTE "If you wish to modify this program, please "
BYTE "send me a copy.",0dh,0ah,0
|
十六进制代码 0Dh 和 0Ah 也被称为 CR/LF (回车换行符)或行结束字符。
1
2
3
4
|
greeting1 BYTE "Welcome to the Encryption Demo program "
和
greeting1 \
BYTE "Welcome to the Encryption Demo program "
|
行连续字符(\)把两个源代码行连接成一条语句,它必须是一行的最后一个字符。上面的语句是等价的。
DUP 操作符
1
2
3
|
BYTE 20 DUP ( 0 ) ;20 个字节,值都为 0
BYTE 20 DUP ( ? ) ;20 个字节,非初始化
BYTE 4 DUP ( "STACK" ) ; 20 个字节:
|
定义 WORD 和 SWORD 数据
1
2
3
|
word1 WORD 65535 ;最大无符号数
word2 SWORD -32768 ;最小有符号数
word3 WORD ? ;未初始化,无符号
|
1
2
|
val1 DW 65535 ;无符号
val2 DW -32768 ;有符号
|
也可以使用传统的 DW 伪指令
偏移量 |
数值 |
0000 |
1 |
0002 |
2 |
0004 |
3 |
0006 |
4 |
0008 |
5 |
1
|
array WORD 5 DUP (?) ; 5 个数值,未初始化
|
定义 DWORD 和 SDWORD 数据
1
2
3
|
val1 DWORD 12345678h ;无符号
val2 SDWORD -2147483648 ;有符号
val3 DWORD 20 DUP (?) ;无符号数组
|
1
2
|
val1 DD 12345678h ;无符号
val2 DD -2147483648 ;有符号
|
偏移量 |
数值 |
0000 |
1 |
0004 |
2 |
0008 |
3 |
000C |
4 |
0010 |
5 |
定义 QWORD 数据
1
2
|
quad1 QWORD 1234567812345678h
quad1 DQ 1234567812345678h
|