汇编学习1
环境搭建
链接:https://pan.baidu.com/s/1LHbEvY6aZ8pG8IbVDyvAsg?pwd=fduy
提取码:fduy
将压缩包中的MASM复制到D盘根目录,然后默认安装dosbox(注意不要修改安装路径)
打开安装好的dosbox
1 | mount c d:masm |
即将d:masm挂载至c盘
1 | c: |
进入c盘
1 | dir |
查看当前路径下文件
1 | debug |
进入debug汇编环境
1 | r |
查看寄存器值
1 | r ax |
修改寄存器ax的值
1 | d 1000:0 |
查看1000:0内存中的数据
1 | d 0000:0000 f |
查看0000:0000内存中的f个数据
1 | e 0000:0000 12 15 34 44 |
修改0000:0000内存中的数据为12 15 34 44
1 | a 073f:0100 |
修改CS:IP指向的指令
1 | t |
执行CS:IP处的一条指令
1 | u 073f:0100 |
将073f:0100处机器码指令翻译为汇编指令
物理地址
CPU访问内存单元时需要给出内存单元地址,每个内存单元有个唯一的地址,称作物理地址
8086地址总线为20,运算器一次最多处理16位的数据,因此8086采用两个16位 的地址(段地址、偏移地址),来合成一个20位的物理地址
物理地址 = 段地址 * 16 + 偏移地址
注意,内存并没有分段,段的划分来自cpu
偏移地址16位,所以一个段的长度最多64K
不同的段地址和偏移地址可以形成同一个物理地址
四个段寄存器
代码段寄存器CS、数据的寄存器DS、栈段寄存器SS、附加段寄存器ES
8086寄存器
8086 CPU 中寄存器总共为 14 个,且均为 16 位。
即 AX,BX,CX,DX,SP,BP,SI,DI,IP,FLAG,CS,DS,SS,ES 共 14 个
通用寄存器
AX,BX,CX,DX称作为数据寄存器:
AX (Accumulator):累加寄存器,也称之为累加器;
BX (Base):基地址寄存器;
CX (Count):计数器寄存器;
DX (Data):数据寄存器;
可拆分为H, L两个8位寄存器
段寄存器
CS (Code Segment):代码段寄存器;
DS (Data Segment):数据段寄存器;
SS (Stack Segment):堆栈段寄存器;
ES (Extra Segment):附加段寄存器;
SP和BP又称作为指针寄存器
SP (Stack Pointer):堆栈指针寄存器;
BP (Base Pointer):基指针寄存器;
SI和DI又称作为变址寄存器
SI (Source Index):源变址寄存器;
DI (Destination Index):目的变址寄存器;
控制寄存器
IP (Instruction Pointer):指令指针寄存器;
FLAG:标志寄存器;
寄存器组合
CS:IP 指向当前指令
SS:SP 指向栈顶元素
指令
mov指令
- mov ax,12 将16进制的12移至ax寄存器
- mov bx,ax 将ax寄存器的值赋给bx
- mov ch,10 将16进制的10移至cx寄存器高8位
- mov ch,al 将ax低8位移至cx高8位
mov ds,10, mov cs,4 是错误的,不可以将立即数赋给段寄存器,需要先把立即数赋给通用寄存器,再将通用寄存器赋给段寄存器
add指令
- add ax,10 将16进制的10累加在ax
- add ax,bx
mul指令
mov al,64
mov bl,a
mul bl 计算16进制64*A并存在ax中
mov ax,64
mov bx,2710
mul bx 计算16进制64*2710并存在dx ax中
div指令
mov ax,2710
mov bl,64
div bl 计算16进制2710/64并存在al中(ah存余数)
mov dx,f
mov ax,4240mov bx,2710
div bx 计算16进制f4240/2710并存在ax中(dx存余数)
AX ÷ BL = AL······AH
DX-AX ÷ BX = AX······DX
and,or指令
mov al,63(01100011B)
and al,3b(00111011B) 结果al=23(00100011B)
shl,shr指令
mov al,48
shl al,1 al左移1位(舍高位,右补0)
inc,dec指令
- inc ax ax自增
jmp指令
- jmp 2AE3:3 修改cs为2AE3,修改ip为3
- jmp ax 仅修改ip为ax寄存器的值
内存中字的存储
8086cpu,16位作为一个字,存储在一个16位的寄存器中,高8位放高字节,低8位放低字节;存储在两个8位的内存单元中,高8位放高地址,低8位放低地址
cpu从内存中读取数据
将1000:0读入al
1 | mov bx, 1000H |
将al写入1000:0
1 | mov bx, 1000:0 |
注意,mov ds, 1000H是错误的,不能给ds寄存器立即数,必须通过一个通用寄存器中转
栈
8086可以将一段内存当作栈使用
ss为栈段寄存器,sp为栈顶指针寄存器,任何时刻ss:sp指向栈顶元素
1 | mov ax, 1000H |
栈越界问题,栈满再push,栈空再pop,都会发生越界问题,但是汇编不保证不会越界,由程序员自己注意越界问题