汇编语言主要操作的是寄存器
通用寄存器
在CPU中,有八个通用寄存器
AX--(add,代表相加,累加的意思)累加器,使用频度最高,用于算术、逻辑运算以及与外设传送信息等;
BX--(base,代表基地址,存放地址的寄存器)基址寄存器,常用做存放存储器地址;
CX-- (base,代表基地址,存放地址的寄存器) 计数器,作为循环和串操作等指令中的隐含计数器;
DX--(data,数据) 数据寄存器,常用来存放双字长数据的高16位,或存放外设端口地址。
8086有4个可以分为8个8位的寄存器也可以作为4个16位数据寄存器:AX:AH,AL BX:BH,BL CX:CH,CL DX:DH,DL
变址寄存器
SI--是源变址寄存器(Source)
DI--是目的变址寄存器(Destination)
主要用途:串操作类指令中,SI和DI具有特别的功能
指针寄存器
BP (base Point) 基址指针寄存器,表示数据在堆栈段中的基地址
SP (stack Point)-- 堆栈指针寄存器,指示栈顶的偏移地址,SP不能再用于其他目的,具有专用目的
主要用途:SP和BP寄存器与SS段寄存器联合使用以确定堆栈段中的存储单元地址
指令指针寄存器
IP--指令指针寄存器
主要用途:IP 和段寄存器CS一起使用,用来确定一条指令的物理地址,也就是cs段基址偏移 指明了CPU要执行的那条指令
计算机通过CS : IP寄存器来控制指令序列的执行流程
4个段寄存器
百度百科:086CPU有20根地址线,最大可寻址内存空间为1MB。而8086的寄存器只有16位,指令指针(IP)和变址寄存器(SI、DI)也是16位的。用16位的地址寻址1MB空间是不可能的。所以就要把内存分段,也就是把1MB空间分为2^4,即16个段,每段不超过64KB(2^16,16位数据线就可以寻址)。在8086中设置4个16位的段寄存器,用于管理4种段:CS是代码段,DS是数据段,SS是堆栈段,ES是附加段。把内存分段后,每一个段就有一个段基址,段寄存器保存的就是这个段基址的高16位,这个16位的地址左移四位(后面加上4个0)就可构成20位的段基址
物理地址:存存储器的实际地址,cpu读取存储器是所使用的地址
逻辑地址:是在程序中使用的地址,由段地址和偏移地址组成,表示形式“段地址:偏移地址”
段地址:是指在逻辑段在主存中的起始位置
段内偏移地址:是指在主存单元距离段首地址的偏移量,由于8086cpu是16位寄存器,一段空间地址最大不超过64KB=2^16B,段空间是以16字节对齐的,所以段的空间是16的倍数开辟内存的
段的概念:内存没有分段,段划分是由于8086cpu用"物理地址=段地址+偏移地址"的方式给出内存单元的物理地址,使我们可以用分段的方式管理内存,所以不同的段是可以重叠的也就是不同的段对应相同的物理地址
例如:1001:2 地址是10012 1000:12 地址也是10012 不同的段对应的地址是一样的
段地址放在段寄存器中,偏移地址放在(IP)指令寄存器中,通过段寄存器和偏移寄存器确定物理地址,访问内存
注意:任何时刻,cs:IP存放的都是指令也就是说cpu读取cs:ip中的内容都当作指令执行,也就是规定了4个段寄存器有自己的属性
Flag 标志寄存器
Flag 标志寄存器, 存放各种标志的,标志寄存器都是16位寄存器。
标志寄存器中的有效位都是以F结尾的,它们是如下几个:
①OF(Overflow Flag)溢出标志,溢出时为1,否则置0.标明一个溢出了的计算
什么是溢出
- 处理器内部以补码表示有符号数
- 8位表达的整数范围是:+127~-128
- 16位表达的范围是:+32767~-32768
- 如果运算结果超出这个范围,就产生了溢出
- 有溢出,说明有符号数的运算结果不正确
溢出和进位
- 溢出标志OF和进位标志CF是两个意义不同的标志
- 进位标志表示无符号数运算结果是否超出范围,运算结果仍然正确;
- 溢出标志表示有符号数运算结果是否超出范围,运算结果已经不正确。
溢出和进位的对比
例1:3AH + 7CH=B6H
无符号数运算: 58+124=182
范围内,无进位
有符号数运算: 58+124=182
范围外,有溢出
例2:AAH + 7CH=(1)26H
无符号数运算: 170+124=294
范围外,有进位
有符号数运算: -86+124=28
范围内,无溢出
如何运用溢出和进位
- 处理器对两个操作数进行运算时,按照无符号数求得结果,并相应设置进位标志CF;同时,根据是否超出有符号数的范围设置溢出标志OF。
- 应该利用哪个标志,则由程序员来决定。也就是说,如果将参加运算的操作数认为是无符号数,就应该关心进位;认为是有符号数,则要注意是否溢出。
溢出的判断
- 判断运算结果是否溢出有一个简单的规则:
- 只有当两个相同符号数相加(包括不同符号数相减),而运算结果的符号与原数据符号相反时,产生溢出;因为,此时的运算结果显然不正确
- 其他情况下,则不会产生溢出
②SF(Sign Flag)符号标志,结果为负时置1,否则置0.
③ZF(Zero Flag)零标志,运算结果为0时置1,否则置0.
④CF(Carry Flag)进位标志,进位时置1,否则置0.注意:Carry标志中存放计算后最右的位.
⑤AF(Auxiliary carry Flag)辅助进位标志,记录运算时第3位(半个字节)产生的进位置。
有进位时1,否则置0.
⑥PF(Parity Flag)奇偶标志.结果操作数中1的个数为偶数时置1,否则置0.
控制标志位:
⑦DF(Direction Flag)方向标志,在串处理指令中控制信息的方向。
⑧IF(Interrupt Flag)中断标志。
⑨TF(Trap Flag)陷井标志
它们在标志寄存器中的分布情况如下所示:
标志寄存器通常用来存储PSW,即程序状态字,Program Status Word
标志寄存器中只有0、2、4、6、7、8、9、10、11有特殊意义,其他无用
debug中常见的指令
a +地址 汇编,代表我们可以从这个地址开始写汇编代码
u +地址 从这个地址开始查看反汇编
U+机器码文件
如果你有一个写到文件的机器码文件,可以当做debug的参数传入,然后u,就可以显示文件中汇编代码了,把机器代码反汇编成了汇编代码了
T=地址 单步步入(在vs中,相当于F11键)
P=地址 从哪个地址开始执行代码,(在vs中,相当于F10键)
r 查看寄存器
R+寄存器名称 可以修改寄存器的内容,比如 r cx 然后回车,输入值
G从CS:IP指向的指令开始执行程序,直到程序结束或遇到INT 3。
G=地址;从指定地址开始执行程序,直到程序结束或遇到INT 3。
G 断点1[,断点2,…断点10];从CS:IP指向的指令开始执行程序,直到遇到断点。
G=地址 断点1[,断点2,…断点10]从指定地址开始执行程序,直到遇到断点
D +地址 从哪个地址开始部分数据显示 (可以显示一段内存中的数据)
n 文件名 (本地创建一个文件, 例如n hello ,不用加双引号包裹)
e 指定地址写入,可以指定地址写入一段数据 如 e 100 “helloworld$” 字符串要用双引号用$做结尾 如果是字符就用单引号 而且要空格分隔单个字符 e 100 ‘h’ ‘e’ ‘l’ ‘l’ ‘$’
w 把汇编代码写入到文件(文件是由n指令创建的),w是根据cx来决定写入的代码的字节数
还有很多其他命令自己百度
命令操作例子:
A命令如下
E命令
U命令
D命令
R命令
n命令
生成文件在当前路径
W命令