《汇编语言》知识重点总结

本文档详细介绍了汇编语言的基础知识,包括寄存器、字节、字和双字的概念,以及各种汇编指令的使用方法,如数据传送指令、算数运算指令、逻辑指令、转移指令等。同时,还探讨了汇编语言在实际应用中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

《汇编语言》

前言

正式工作之后打算着手做一些逆向方面的研究,听前辈们的建议,必须先把汇编学会,于是我用第一个月把《汇编语言》(第三版-王爽著)看了一遍,但是人的记忆力是有限的,所以打算以博客的形式再回忆一遍,相信通过这种形式,能让自己对知识理解的更加模块化和具体化,也方便自己日后复习,同时也方便了看到这篇博客的同道中人。

作用

汇编语言在整个计算机编程语言中的地位可以说是没什么用,很少有人会直接拿汇编语言去写项目,如果这么干的话,不得麻烦死(但是不排除确实有这种需求的时候的做法)。更多时候汇编语言的使用场景是在反编译别人的二进制代码之后,对汇编代码的逻辑还原,并且对于计算机系统整体的理解,我相信没有什么比学习汇编语言更快、更好。

名词、汇编指令的示例和说明(8086cpu)

  • 寄存器:用于存放cpu的数据信息,共14个,分别是:AX,BX,CX,DX,SI,DI,SP,BP,IP,CS,SS,DS,ES,PSW。

  • 字节、字和双字:1双字(DWROD)=2字(WORD)=4字节(byte)。1字节(byte)=8位(bit),比如,寄存器ax是16位寄存器,在内部可以在分为ah和al,分别代表高8位和低8位。

  • 内存访问:一般利用寄存器ds,es,ss才可以间接访问内存,比如要访问2000:0200位置的数据,并将该位置的数据传送入ax,应该这样:

mov ax,2000h
mov ds,ax
mov si,200h
mov ax,ds:[si]
  • 栈内存:在内存访问中有一类特殊的访问,就是栈内存,在操作栈的时候,最好指定一块用于自己使用的内存区域,以便自定义栈的大小和位置。示例:
assume cs:code
stack segment 
    db 128 dup (0) 
stack ends
code segment
start:
    mov ax,stack
    mov ss,ax
    mov sp,128    ;目前栈顶在ss:sp处(即stack:128),也就是上面定义的stack中的128字节
    mov ax,'a'
    push ax    ;将'a'入栈,栈顶在ss:sp处(即stack:126)
    push ax
    pop bx    ;出栈,将数据保存在bx中
    mov ax,4c00h
    int 21h
code ends
end start
  • 标志位:在内存中占1字节大小,用于运算和程序中的状态等。常用的标志有ZF,PF,SF,CF,OF,DF
ZF:是否为0

PF:1的个数是否为偶数

SF:是否为负数

有符号整数,只看结果是不是大于7,也就是首位是不是0

CF:是否存在进位或借位(无符号整数)

直接进行无符号运算,首位进位就置1

OF:是否存在溢出(有符号整数)

16位cpu,有符号溢出范围79H(127),-80H(128)

DF:方向标志位,与movsb配合使用
  • 指令
数据传送指令:
mov:数据传送
示例:mov ax,bx
说明:将bx中的数据传送到ax中,因为使用的是ax和bx,所以数据的长度是16位,下面的例子都相同,如果有操作数据中有寄存器,那么按照寄存器的数据长度计算

push:入栈
示例:push ax
解释:将ax的数据入栈,传送到ss:sp栈顶处

pop:出栈
示例:pop ax
解释:将ss:sp位置的数据出栈,传送入ax中

pushf:所有标志位入栈
示例:pushf
解释:标志位入栈,防止后面的操作对标志位产生影响的通常做法

popf:标志位出栈
示例:popf
解释:标志位出栈,用于还原入栈的标志位

xchg:交换,目前没用到
算数运算指令
add:加法
示例:add ax,2
解释:将ax中的数据加2,即ax+0002h

sub:减法
示例:sub ax,2
解释:将ax中的数据减2,即ax-0002h

adc:加法(带符号位)
示例:adc ax,2    ;CF=1
解释:将ax中的数据加3,即ax+0002h+1h

sbb:减法(带符号位)
示例:sbb ax,2    ;CF=1
解释:将ax中的数据减3,即ax-0002h-1h

inc:自增
示例:inc si
解释:将si中的数据加1,常用在循环或条件转移中

dec:自减
示例:dec ax
解释:将ax中的数据减1

cmp:比较
示例:cmp ax,0
解释:相当于减法,ax-0,只不过不影响寄存器的值,而只影响标志寄存器,因为条件转移指令是依据标志寄存器的指令,所以cmp常与条件转移指令配合使用进行条件转移

mul:乘法
示例:mul bx或mul bl
解释:分为两种情况:
1. 指令参数是8位寄存器如bl时,乘数1默认放在al寄存器中,另一个乘数2放在8位寄存器如bl中,结果存在ax中
2. 指令参数是16位寄存器如bx时,乘数1默认放在ax寄存器中,另一个乘数2是指定的16位寄存器如bx中的数据,结果的高16位存在dx,低16位存在ax中

div:除法
示例:div bx或div bl
解释:同样分为两种情况:
1. 指令参数是8位寄存器时,被除数(除法前面那个数。。。)则为16位,默认存放于ax中,除数则是存放于指定8位寄存器如bl中,结果为:al存储商,ah存储余数
2. 指令参数是16位寄存器时,被除数则为32位,默认存放于ax和dx中,dx存高16位,ax存低16位,除数存放于指定16位寄存器如bx中,结果:ax存储商,dx存储余数

aaa:目前没有用到
逻辑指令
and:逻辑与
示例:and al,11011111b
解释:示例中结果是将al中第6位置为0,其他位保持不变,常用与简化运算如,将小写字母转化为大写字母,只需要将字母与11011111做逻辑与运算即可实现

or:逻辑或
示例:or al,00100000
解释:示例中结果是将al中第6位置为1,其他位保持不变,同样也能实现将大写字母转化为小写字母的简化运算,需要将字母与00100000做逻辑或运算即可实现

not:逻辑非,不常用
示例:
解释:

xor:逻辑异或,目前不常用
示例:
解释:

test:不常用
shl:逻辑左移
示例:shl al,1或mov cl,3;shl al,cl
解释:逻辑左移的意思就是左移后,移出的数据存放在标志寄存器CF中,而最低位用0补齐,也分为两种情况:
1. 左移1位:直接shl al,1即可
2. 左移超过1位:需要先将欲移动的位数据存入cl中,再通过左移cl个位的数据来实现

shr:逻辑右移
示例:shr al,1或move cl,2;shr al,cl
解释:逻辑右移与逻辑左移类似,这里就不多讲了,同样也是两种情况

sal
sar
rol
ror
rcl
rcr
转移指令
无条件转移指令
jmp:无条件转移指令
示例:jmp short s;s:inc ax
解释:jmp转移指令可以实现段内短转移、段内近转移和段间转移这三种基本需求
1. 段内短转移:只对IP寄存器修改,修改范围为-128~127,也就是说向前最多转移+127个字节,向后最多转移-128个字节
2. 段内近转移:与短转移基本相同,不过是16位的位移,即修改IP的范围是-32768~32767
3. 远转移(段间转移):可以转移到指定的内存处,上面的两个转移只是在同一个段中的转移,是根据位移定位的转移方式,而远转移可以指定转移的目的地址

条件转移指令
jcxz:如果cx寄存器的值为0,则转移到指定标号
示例:mov cx,0;jcxz s
解释:如果条件满足cx寄存器的值为0,则转移到指定的标号处,常用的场景是:遍历一个以'0'字符结尾的字符串,根据这个0判断字符串是否到末尾的简单实现方式

je:如果cmp得差结果等于0,则转移到指定标号
示例:mov bx,3;cmp bx,3;je s
解释:将会转移到s处

jb:如果cmp的差结果小于0,则转移到指定标号
示例:mov bx,3;cmp bx,4;jb s
解释:将会转移到s处

ja:如果cmp的差结果大于0,则转移到指定标号
示例:mov bx,3;cmp bx,2;ja s
解释:将会转移到s处

jnb:如果cmp的差结果不小于0,则转移到指定标号
示例:mov bx,3;cmp bx,3;jnb s
解释:将会转移到s处

jna:如果cmp的差的记过不大于0,则转移到指定标号
示例:mov bx,3;cmp bx,3;jna s
解释:将会转移到s处

循环指令
loop:汇编语言中的循环语句
示例:mov cx,10;loop s
解释:将s程序段循环执行10次(循环次数由cx的值指定)

过程
call:调用子程序,常与ret成对使用
示例:call s;s:ret
解释:转移到子程序,类似于转移指令,但相当于执行了
push IP
jmp near s这两条指令,记录了转移的位置,可以使用ret返回此IP的位置

ret:在子程序中同于返回call的指令处,常与call成对使用,并且是近转移
示例:call s;s:ret
解释:从子程序跳出,相当于执行了
pop IP,程序执行的下一条语句就是原来call的IP的地址,从而实现了近转移

retf:在子程序中同于返回call的指令处,常与call成对使用,并且是远转移
示例:call s;s:retf
解释:从子程序跳出,相当于执行了
pop IP
pop CS程序执行的下一条语句就是原来call的IP的地址,从而实现了远转移

中断
int:系统中断
示例:mov ax,4c00h;int 21h
解释:BIOS和DOS都提供了一些默认的中断进程,用于持续检测中断码,如果接受到中断码,则会在TF=1的情况下在下一条指令去执行可屏蔽中断进程,我们也可以自定义中断进程去替代系统的中断进程。示例中的中断是去执行21号中断的ah=4c的子程序,子程序为退出当前DOS

iret:与int配合使用,在子程序中返回,与ret,retf类似
处理机控制指令
cld:设置DF为0(即正向拷贝)
示例:cld;rep movsb
解释:设置标志寄存器DF为0,即设置拷贝的方向为正向

std:这是DF为1(即反向拷贝)
示例:std;rep movsb
解释:设置标志寄存器DF为1,即设置拷贝的方向为反向

cli:设置TF标志位为1
示例:cli
解释:设置TF为1后,当接受到可屏蔽中断时,会在下一条指令执行中断

sti:设置TF标志位为0
示例:sti
解释:设置TF为0后,当接受到可屏蔽中断时,会忽略中断继续执行当前程序直至结束

nop:添加一个占位的一字节数据
示例:funcend:nop
解释:常用来记录子程序的段结束的位置,比如offset funcend就可以获取func结束位置的偏移地址

clc
cmc
stc
hlt
wait
esc
lock
串处理指令
movsb:复制字符串
示例:rep movsb
解释:可以正向或反向复制指定为的字符串到目标地址,参数必须将ds:si源地址、es:di目的地址、cx长度、标志DF指定,然后调用rep movsb

movsw
示例:
解释:

cmps
scas
lods
stos
配合使用:
rep
repe
repne

书中的一些值得注意的问题(自己的笔记上的内容,某些描述可能不是很准确,可以选择性跳过)

mov ax,0 可以用sub ax,ax替代,而且后者2字节,前者3字节
当16进制数,首位数字为英文,则需要在前面加上0,比如:0A432H
在汇编程序中,mov al,[0]指令与debug程序不同,汇编编译器会将它解释为mov al,0
DOS和合法程序都不会使用0:200~0:2ff这段256字节的空间
直接DEBUG显示的CS就是当前程序段的字节长度
为什么mov 4c00h;int 21h长度为5字节
暂存数据的时候,一般用栈
bp寄存器默认使用ss作为段寄存器
没有寄存器名存在的情况下指定内存单元的长度:mov word/byte ptr [bx],1
push/pop只对字操作
在10.1节,ret和retf的示例中,在执行命令之前,为什么都要mov bx,0
mul乘法,与div除法原理相似,都分为8位和16位的计算
16位cpu,有符号溢出范围79H(127),-80H(128)
DF:方向标志位,与movsb配合使用
adc指令的意义:进行大数的加法或减法 
inc和loop不影响cf位
cmp指令只会影响标志位
CF能说明操作符的大小
SF=1并不能说明运算的结果的正负,因为可能发生溢出
但SF和OF同时可以说明正负
SF=1,OF=1:(ah)<(bh)
SF=1,OF=0:(ah)>(bh)
SF=0,OF=1:(ah)<(bh)
SF=0,OF=0:(ah)>=(bh)
cld和std分别设置DF为0(正向)和1(反向)
Debug中的标志位对应关系
flag:1--0
OF:OV,NV
SF:NG,PL
ZF:ZR,NZ
PF:PE,PO
CF:CY,NC
DF:DN,UP
loop执行分两步
cx--
cx不等于0,转移
中断过程
取得中断类型吗N
pushf,将标志寄存器入栈保存
TF=0,IF=0
push cs
push ip
(IP)=4*N,(CS)=4*N+2
动态获取到一段代码的长度,可以设置一个nop字节,获取长度只需要:

mov cx,offset do0end-offset do0
do0:
    mov xx,xxx
    mov 4c00h
    int 21h
do0end:nop

jmp short s占2字节内存
设置栈顶的ss和sp之间不会响应任何中断,所以在实验二的时候,执行mov ss,0后,mov ax,0执行了,只是debug不能将它中断显示
一般在中断例程中还存在子程序,一般通过ah来指定
如果将字符串后的0写成字符'0',则利用jcxz无法跳转
在进行逻辑移位shl或shr时,移位大于1,必须用cl保存位移数,并将最后一次移出的保存到CF中
在CMOS RAM中,端口为70h(地址端口)和71h(数据端口)存储时间信息的单元分别为:秒:0分:2时:4日:7月:8年:9,都占一个字节
在PC中,外中断可分为可屏蔽中断和不可屏蔽中断
可屏蔽中断在IF=1时,cpu会在执行完当前指令后响应中断,IF=0则不响应此中断
不可屏蔽中断是cpu必须响应的中断,一般不会使用
设置IF:sti,设置IF=1; cli,设置IF=0,IF=0不会执行屏蔽中断
通码:按下键盘的一个键产生的扫描码;断码:松开一个键产生的扫描码,
断码=通码+80h
都被送到60h端口
扫描码一个字节中,通码的第7位为0,断码第7位为1
地址标号和数据标号
地址标号,只能在代码段使用
数据标号,不仅表示内存单元的地址,还表示内存单元的长度,与地址标号不同是标号后无符号“:”
直接定址表:可以通过依据数据,直接计算出所要找的元素的位置的表
键盘缓冲区的字单元中,高位字节存储扫描码,低位字节存储ASCII码。
int 16h用于从键盘缓冲区读取字符,ah存储扫描码(高位),al存储字符(低位)

转载于:https://www.cnblogs.com/qjx-2016/p/9375730.html

汇编语言(各章知识点) 课程介绍 第1章 预备知识  1.1 汇编语言的由来及其特点   1 机器语言   2 汇编语言   3 汇程序   4 汇编语言的主要特点   5 汇编语言的使用领域  1.2 数据的表示类型   1 数值数据的表示   2 非数值数据的表示   3 基本的数据类型  1.3 习题 第2章 CPU资源存储器  2.1 寄存器组   1 寄存器组   2 通用寄存器的作用   3 专用寄存器的作用  2.2 存储器的管理模式   1 16位微机的内存管理模式   2 32位微机的内存管理模式  2.3 习题 第3章 操作数的寻址方式  3.1 立即寻址方式  3.2 寄存器寻址方式  3.3 直接寻址方式  3.4 寄存器间接寻址方式  3.5 寄存器相对寻址方式  3.6 基址加变址寻址方式  3.7 相对基址加变址寻址方式  3.8 32位地址的寻址方式  3.9 操作数寻址方式的小结  3.10 习题 第4章 标识符表达式  4.1 标识符  4.2 简单内存变量的定义   1 内存变量定义的一般形式   2 字节变量   3 字变量   4 双字变量   5 六字节变量   6 八字节变量   7 十字节变量  4.3 调整偏移量伪指令   1 偶对齐伪指令   2 对齐伪指令   3 调整偏移量伪指令   4 偏移量计数器的值  4.4 复合内存变量的定义   1 重复说明符   2 结构类型的定义   3 联合类型的定义   4 记录类型的定义   5 数据类型的自定义  4.5 标号  4.6 内存变量标号的属性   1 段属性操作符   2 偏移量属性操作符   3 类型属性操作符   4 长度属性操作符   5 容量属性操作符   6 强制属性操作符   7 存储单元别名操作符  4.7 表达式   1 进制伪指令   2 数值表达式   3 地址表达式  4.8 符号定义语句   1 等价语句   2 等号语句   3 符号名定义语句  4.9 习题 第5章 微机CPU的指令系统  5.1 汇编语言指令格式   1 指令格式   2 了解指令的几个方面  5.2 指令系统   1 数据传送指令   2 标志位操作指令   3 算术运算指令   4 逻辑运算指令   5 移位操作指令   6 位操作指令   7 比较运算指令   8 循环指令   9 转移指令   10 条件设置字节指令   11 字符串操作指令   12 ASCII-BCD码调整指令   13 处理器指令  5.3 习题 第6章 程序的基本结构  6.1 程序的基本组成   1 段的定义   2 段寄存器的说明语句   3 堆栈段的说明   4 源程序的结构  6.2 程序的基本结构   1 顺序结构   2 分支结构   3 循环结构  6.3 段的基本属性   1 对齐类型   2 组合类型   3 类别   4 段组  6.4 简化的段定义   1 存储模型说明伪指令   2 简化段定义伪指令   3 简化段段名的引用  6.5 源程序的辅助说明伪指令   1 模块名定义伪指令   2 页面定义伪指令   3 标题定义伪指令   4 子标题定义伪指令  6.6 习题 第7章 子程序库  7.1 子程序的定义  7.2 子程序的调用返回指令   1 调用指令   2 返回指令  7.3 子程序的参数传递   1 寄存器传递参数   2 存储单元传递参数   3 堆栈传递参数  7.4 寄存器的保护与恢复  7.5 子程序的完全定义   1 子程序完全定义格式   2 子程序的位距   3 子程序的语言类型   4 子程序的可见性   5 子程序的起始结束操作   6 寄存器的保护恢复   7 子程序的参数传递   8 子程序的原型说明   9 子程序的调用伪指令   10 局部变量的定义  7.6 子程序库   1 建立库文件命令   2 建立库文件举例   3 库文件的应用   4 库文件的好处  7.7 习题 第8章 输入输出中断  8.1 输入输出的基本概念   1 I/O端口地址   2 I/O指令  8.2 中断   1 中断的基本概念   2 中断指令   3 中断返回指令   4 中断子程序  8.3 中断的分类   1 键盘输入的中断功能   2 屏幕显示的中断功能   3 打印输出的中断功能   4 串行通信口的中断功能   5 鼠标的中断功能   6 目录文件的中断功能   7 内存管理的中断功能   8 读取设置中断向量  8.4 习题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值