【汇编】基础随笔
随笔&一些概念
地址
B800:0000 400 显存地址。
冒号左边的是段地址,冒号右边的是偏移地址。
段地址保存在段地址寄存器中,偏移地址保存在偏移地址寄存器中。
CPU中可以存放地址信息和数据信息的地方叫做寄存器。
修改寄存器中的内容从而控制CPU(控制整个计算机)
DosBox
u指令:将某个内存地址开始的字节当做指令。
d指令:将某个内存地址开始的字节当做数据。
a指令:输入指令。
r指令:查看寄存器。
- r 寄存器:修改某个寄存器中的值。
t指令:执行。
e指令:改写内存中的内容
地址线&数据线&控制线
地址线:决定了CPU的寻址能力。
数据线:决定了CPU和其他部件的交互能力,进行数据传送时一次性能传送多少字节的能力。
控制线:决定了CPU对其他部件的控制能力。
寄存器
数据寄存器
AX BX CX DX
通用寄存器,存放数据的。一个寄存器,两个字节,16位寄存器。
这4个寄存器可以分割为两个子寄存器,高8位和低8位:0 - FF(255)
AX = AH + AL
字节型数据 8bit -> byte -> 8位寄存器。
字型数据 16bit -> 2byte -> 16位寄存器,分别会放在高位寄存器和低位寄存器中。
内存寄存器
8086CPU有20个根地址线,即0~FFFFH。
物理地址计算
基础地址 + 偏移地址(0 ~ FFFFH) = 物理地址。
计算公式:段地址 * 0x10 + 偏移地址 = 物理地址
只要物理地址满足上述公式,都可以找到同一个物理地址。
偏移地址的取值范围在 0H ~ FFFFH之间。
段地址寄存器
ds, es, ss, cs
偏移地址寄存器
sp, bp, si, di, ip, bx
CPU如何区分指令和数据
在内存中,指令和数据是没有区别的,都是二进制数据。在CPU工作的时候才有区分。
在8086CPU中的任意时刻,CPU将CS:IP所指向的内容,全部当做指令来执行。
如果在某个内存地址中输入了一系列的指令,想执行这些指令,就把CS:IP的地址修改到该地址。
CS:IP 修改只能通过jmp修改,不可以通过mov修改。
指令执行的过程
- CPU从CS:IP所指向内存单元读取指令,存放到指令缓存器中。
- IP = IP + 所读指令的长度,从而指向下一条指令。
- 执行指令缓存器的内容,回到步骤1。
当跳转后,ip会被改变,第2部变化的ip随之变化,指向的下一条指令不会生效。
为了实现call指令才这么设计的(函数跳转要记录地址)。
假设读取指令之后直接执行,CS:IP马上改变,无法记录ret返回的地址(call执行会记录当前的IP或CS:IP压入栈中,又因为马上改变所以IP变了,记录了错的IP,就返回不去了)。
那么call和ret就无法生效。
一些指令
mov
移动指令。
将逗号右边的移入数据逗号左边。
mov ax, 5
数位不一致会报错。
在使用mov的时候,要保证数据和寄存器之间,位数一致性。
add
加法指令。
add ax, 5
=> ax = ax + 5
8位寄存器,进行8位运算,保存8位数据。寄存器是互相独立的,AL就是AL,AH就是AH,不会互相影响。
意思是:如果add al, 5
的话,那么它只会对al寄存器进行运算,结果只限定在al里。如16位和16位,结果会在16位寄存器里(16位寄存器进行16位运算,结果会保存在16位里)。
ax不能和ah al相加,是独立的。
如果相加超出了16位(最大值),就保存从右开始的4位16进制。超过的值会被保存至其他地方。
比如AX寄存器准备保存1046C,只保存046C;AL寄存器保存102,只保存02;
sub
减法指令,结果赋值到左边寄存器,与add相反
sub ax, 1
sub ax, bx
jmp
跳转指令。
jmp 内存地址。
jmp 寄存器。
- 直接跳转寄存器的话,是修改了IP寄存器。
call
转移指令。与之对应的是 RET。
改变的是CS:IP地址。
指令的操作形式(随笔总结)
- mov 寄存器, 数据
- mov 寄存器, 寄存器
- mov 寄存器, 内存单元
mov ax, [0]
- mov 内存单元, 寄存器(也有相反的顺序)
mov ax, 1000
mov ds, ax
mov [0], cs
- mov 段寄存器, 寄存器(也有相反的顺序)
mov ax, 1000
mov ds, ax
mov ax, ds
...
字型数据
一个字型数据,存放在内存中,可以由2个连续的地址的内存单元组成。
- 高地址内存单元存档字型数据的高位字节。
- 低地址内存单元存档字型数据的低位字节。