Skip to content

框架

assembly
.386
.MODEL FLAT

ExitProcess PROTO NEAR32 stdcall, dwExitCode:DWORD

INCLUDE io.h            ; header file for input/output

cr      EQU     0dh     ; carriage return character
Lf      EQU     0ah     ; line feed

.STACK  4096            ; reserve 4096-byte stack

.DATA                   ; reserve storage for data

.CODE                           ; start of main program code
_start:

PUBLIC _start                   ; make entry point public
END                             ; end of source code
  • .386 伪指令,它表示这是一个 32 位程序,能访问 32 位寄存器和地址。
  • .DATA 可以用于定义变量
  • .CODE 伪指令标识的程序区段包含了可执行的指令
  • .STACK 伪指令标识的程序区段定义了运行时堆栈,并设置了其大小
  • ExitProcess 函数的原型,它是一个标准的 Windows 服务。原型包含了函数名、PROTO 关键字、一个逗号,以及一个输入参数列表。ExitProcess 的输入参数名称为 dwExitCode
  • 标号 main 它标记了程序开始执行的地址。

计算机中数的表示

  • 二进制:b
  • 八进制:o
  • 十六进制:h -> 注意和寄存器区别

进制间的转换

有符号和无符号的区别

  • 最高位1为负数
  • 最高位0为正数

补码间的转换

正数:直接转换 负数:按位取反,末位加一

ASCII码

48-57: 0-9
65-90: A-Z
97-122:a-z

数据类型

类型用法大小
BYTE8 位无符号整数,B 代表字节8位
WORD16 位无符号整数16位
DWORD32 位无符号整数,D 代表双(字)32位

寄存器

  • EAX:累加器
  • EBX:基地址寄存器
  • ECX:计数器
  • EDX:总是用来放整数除法产生的余数
  • ESI:源索引寄存器
  • EDI:目标索引寄存器
  • EBP:基址指针
  • ESP:堆栈指针

操作数的三种模式

立即数——指令中含有数据: 常数、equ 寄存器——数据在寄存器中: 寄存器 存储器——数据在存储区域

存储器操作数其中两种方式

直接寻址——地址在指令中给出: 变量名、[常数] 寄存器间接寻址——数据的地址在寄存器中: [寄存器]

标志位

  • ZF——零标志位:结果为0,ZF=1,否则为0
  • SF——符号标志位:运算结果位负时,SF置为1
  • CF——进位标志位:最高位进位,CF=1,不进位为0
  • OF——溢出标志位:两操作数符号相同但结果与符号位相反,OF=1

指令

在几乎所有的汇编语言指令中,左边的操作数是目标操作数,而右边的操作数是源操作数。

复制数据指令

MOV 目的操作数,源操作数

相当于

目的操作数 = 源操作数;

不合法指令

assembly
mov EAX, BL         × 两个寄存器位数不匹配
mov CS, AX          × 往代码段寄存器中传送数据
mov [ESI], [EBX]    × 源目的操作数都在内存
mov AH, 2589H       × 两操作数的位数不匹配
mov ES, DS          × 两操作数都是段寄存器
mov DS,3452H        × 立即数往段寄存器传送数据
mov 5, AH           × 目的操作数为立即数

定义变量

assembly
.data                          ;此为数据区
sum DWORD 0                    ;定义名为sum的变量

输入输出

IO.H中的宏

功能
dtoa 目的操作数,源操作数 ;把源操作数中的双字节数转换成一个11字节长的ASCII码,并存入目的操作数
atod 源操作数 ;转换一个字符串为一双字长的2进制补码数
itoa 目的操作数,源操作数 ;把源操作数(寄存器或存储器)中的单字节数转换成一个6字节长的ASCII码,并存入目的操作数
atoi 源操作数;与atod类似,只是转换的结果存入AX寄存器,并且该数允许的范围是-32768到32767
output输出源操作数中的字符串,该字符串必须以空字符串结束
input 目的操作数,长度输入一个长度为length的字符串,并将该字符串存入目的操作数

算数指令

指令功能
add 目的操作数,源操作数
sub 目的操作数,源操作数
inc 目的操作数自增
dec 目的操作数自减
neg 目的操作数取二进制数补码数
mul 源操作数无符号乘法 乘积为EDX:EAX
imul 源操作数累加器EAX作为另一个乘数
imul 寄存器 源操作数乘积必须目的寄存器长度一致,那么OF、CF清零,否则置为1
imul 寄存器 源操作数 立即数寄存器用来存放乘积,如果乘积和目的寄存器长度一致,那么OF、CF清零,否则置为1
idiv 源操作数源操作数就是除数,被除数为AX(字节)或DX:AX(字)或EDX:EAX(双字) 商放入AL 余数放入AH
div 源操作数无符号

除法溢出:被除数的高半部大于等于除数

数据大小转换

指令功能
cbw字节转换为字;将AL寄存器中的二进制补码数扩展为AX中的字长
cwd字转换为双字;将AX寄存器中的二进制数扩展为DX和AX中的双字
cdq双字转换为四字;将EAX寄存器中的双字扩展为EDX和EAX中的四字

分支和循环

指令功能
jmp StatementLabel无条件转移
cmp 操作数1 操作数2有条件转移

条件转移指令

assembly
j-  statementLabel
无符号描述有符号
a大于g
b小于l
e等于e
n否定n

循环指令

assembly
loop    statementLabel

loop指令执行以下动作:

  • ECX中的值减少
  • 如果ECX中新的值是0,则执行下面的语句
  • 如过ECX中新的值不是0,则执行转移指令到statementLabel

数组

定义数组:

assembly
变量名  DWORD   大小 DUP (?)

取地址:

assembly
lea 目的地址,源数据

取当前项:

assembly
[ebx]

取出数组中下一项的地址:

assembly
add ebx,4

过程

80×86堆栈

分配堆栈:

assembly
.STACK 4096

内容出入堆栈

assembly
push    源操作数
pushw   字源操作数
pushd   双字源操作数
pop     目的操作数

过程体、调用和返回

过程体

assembly
子程序名 PROC near32
        push ebp    ;保存寄存器
        mov ebp esp ;建立堆栈
        ·
        ·
        ·
        pop ebp     ;恢复寄存器
        ret n   ;参数个数×4,释放参数
子程序名 ENDP

调用:

assembly
call 目的过程

宏定义

assembly
name    MACRO   参数列表
        local   标号
        ·
        ·
        ·
        ENDM

局部标号:local

在宏定义体的第一有效行,声明局部标号(多个就写同一行)

串操作

指令功能
cld将DF清零,这样串指令使ESI和EDI的值递增,从左向右处理字符串
std将DF置1,从右向左处理字符串
movs-b:字节、w:字、d:双字;从源串传送到目的串:地址DS:ESI指向的源元素被复制到地址的ES:EDI
cmps-b:字节、w:字、d:双字;为了判断两个串是否相同,那么repe前缀和cmps最好一起使用
scas-b:字节、w:字、d:双字;用来在串中扫描某个特定的串元素是否在串中存在
stos-b:字节、w:字、d:双字;将寄存器中的内容复制为目的串的某个元素了,不影响标志位
lods-b:字节、w:字、d:双字;按照串元素的长度复制源串中的元素到AL,AX和EAX寄存器中

重复前缀

助记符循环条件
repECX>0
repz/repeECX>0 && ZF=1
repnz/repneECX>0 && ZF=0

位运算

assembly
and     目的操作数,源操作数
or      目的操作数,源操作数
xor     目的操作数,源操作数
nor     目的操作数,源操作数
test    目的操作数,源操作数    ;与操作不存结果,影响标志位

移位指令和循环移位指令

shlshr是逻辑移位

assembly
shl 目的地址,count    ;逻辑左,CF:为左边第一位,末尾补0
shr 目的地址,count    ;逻辑右,CF:为右边第一位,首位补0

salsar是算数移位

assembly
sal 目的地址,count    ;算数左,CF:为左边第一位,末尾补0
sar 目的地址,count    ;算数右,CF:为右边第一位,首位为1补1,为0补0

一位移位中,结果符号位的值与源操作数相同则OF置为0,否则置1.