总结一下最近看的汇编知识,cpu是针对8086CPU
汇编指令是机器指令的助记符,同机器指令一一对,每种CPU都有自己的指令集。
汇编语言由3类指令组成。汇编指令,伪指令(没有对应的机器码,由编译器执行,计算机并不执行),其他符号(如+、-、*、/等,由编译器识别,没有对应的机器码)
随机存储器(RAM)在程序的执行过程中可读可写,必须带电存储。例如计算机内存。
只读存储器(ROM)在程序的执行过程中只读,关机数据不丢失。例如计算机硬盘。
指令和数据在存储器里没什么区别都是二进制数据,例如1000100111011000即可以按数据89D8H处理,也可以当成mov ax ,bx指令。
一个储存单元占1byte,存储器被划分成从0开始的储存单元编号,这个编号就是地址。
cpu数据总线分为地址总线,数据总线,控制总线,cpu就是通过他们操作数据。例如读取内存数据步骤1.cpu通过地址总线寻址,2.通过控制总线发出读写信号,3.如果是读数据将地址总线找到的地址的内容读到数据总线,写是将数据总线内的数据写到地址总线找到的地址。
地址总线宽度决定cpu寻找能力;
数据总线宽度决定cpu一次数据传输的大小;
控制总线宽度决定cpu对系统器件的控制能力;
CPU由运算器、控制器、寄存器等器件构成,这些器件靠cpu内部总线相连。
运算器进行信息处理;
控制器控制各种器件进行工作;
寄存器进行信息存储;
通常用来存放一般性的数据,8086CPU有AX、BX、CX、DX四个通用寄存器,它们可分为两个可独立使用的8位寄存器。例如AX(16位) =AH(高8位) +AL(低8位)。
8086CPU采用一种在内部用两个16位地址合成的方法来形成一个20位的物理地址
当8086CPU要读写内存时:
CPU中的相关部件提供两个16位的地址,一个称为段地址,另一个称为偏移地址;
地址加法器将两个16位地址合成为一个20位的物理地址;
地址加法器采用物理地址 = 段地址×16 + 偏移地址的方法用段地址和偏移地址合成 物理地址,然后将地址送到地址总线。
CS为代码段寄存器,IP为;
CPU将CS、IP中的内容当作指令的段地址和偏移地址,用它们合成指令的物理地址;
CPU将CS:IP内容指向的地址当作指令执行,执行完以后ip自动指向下一个地址;
8086CPU提供转移指令修改CS、IP的内容。
jmp 段地址:偏移地址:用指令中给出的段地址修改CS,偏移地址修改IP。如:jmp 2AE3:3
jmp 某一合法寄存器:仅修改IP的内容。如:jmp ax。在含义上好似:mov IP,ax
DS数据段寄存器:通常用来存放要访问数据的段地址
[address值]表示一个偏移地址为address值的内存单元,段地址默认放在ds中
通过数据段段地址和偏移地址即可定位内存单元
mov bx, 1000H ;8086CPU不支持将数据直接送入段寄存器的操作
mov ds, bx ;ds存放数据段地址
mov [0], al ;将al数据(1字节)存到1000H段的0偏移地址处,即10000H
mov ax, [2] ;将数据段偏移地址2处的一个字(8086为2字节)存放到ax寄存器
add cx, [4] ;将偏移地址4处的一个字数据加上cx寄存器数据放到cx寄存器
sub dx, [6] ;dx寄存器数据减去数据段偏移地址6处的字数据存到dx
在基于8086CPU编程的时候,可以将一段内存当作栈来使用。
栈段寄存器SS,存放段地址,SP寄存器存放偏移地址,任意时刻,SS:SP指向栈顶元素
[bx]同样表示一个内存单元,它的偏移地址在bx寄存器等指定寄存器中,段地址默认在ds中,可以手动指定段如ds:[bx],cs:[bx]。
loop指令的格式是:loop 标号,CPU执行loop指令的时候,要进行两步操作,
(cx) = (cx) - 1;
判断 cx 中的值,不为零则转至标号处执行程序,如果为零则向下执行
8086CPU提供以下几大类指令
mov、push、pop、pushf、popf、xchg 等都是数据传送指令,这些指令实现寄存器和内存、寄器和寄存器之间的单个数据传送。
mov指令 mov a,b将b的值传到a。
add、sub、adc、sbb、inc、dec、cmp、imul、idiv、aaa等都是算术运算指令,这些指令实现存器和内存中的数据的算数运算。它们的执行结果影响标志寄存器的sf、zf、of、cf、pf、af位。
add加法指令 add a,b将a+b的值传到a。
sub减法指令 sub a,b将a-b的值传到a。
div除法指令 div a,默认ax寄存器除以a的值,如果除数为8位,则AL存储除法操作的商,AH存储除法操作的余数;
如果除数为16位,则AX存储除法操作的商,DX存储除法操作的余数。。
mul乘法指令 mul a,默认a乘以ax寄存器的值。结果8位:AX中;16位:DX(高位)和 AX(低位)中。
and、or、not、xor、test、shl、shr、sal、sar、rol、ror、rcl、rcr等都是逻辑指令。除了not指外,它们的执行结果都影响标志寄存器的相关标志位。
无条件转移指令,比如,jmp;
条件转移指令,比如,jcxz、je、jb、ja、jnb、jna等;
循环指令,比如,loop;
过程,比如,call、ret、retf;
中断,比如,int、iret。
assume cs:code,ds:data,ss:stack
data segment
dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
data ends
stack segment
dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
stack ends
code segment
start: mov ax,stack
mov ss,ax
mov sp,20h
mov ax,data
mov ds,ax
mov bx,0
mov cx,8
s: push [bx]
add bx,2
loop s
s0: pop [bx]
add bx,2
loop s0
mov ax,4c00h
int 21h
code ends
end start
那些被 code 和 data 伪指令标记的代码和数据区,被称为段。即,程序有代码段和数据段。
一条指令有四个组成部分:
标号(可选):标号(label)是一种标识符,是指令和数据的位置标记。
指令助记符(必需)
操作数(通常是必需的)
注释(可选) ;号开始
NOP(空操作)指令