8086CPU地址总线宽度为20, 也就是说一个内存物理地址是5位,内存地址空间为1Mb;数据总线为16位;寄存器为16位。linux
16位结构的CPU包括如下特性:编程
1,运算符最多处理16位数据。windows
2,寄存器最大宽度为16位。函数
3,寄存器与运算器之间的通路是16位。oop
这里就出现了一个问题,若是由16位推出20位的物理地址呢?ip
因此就出现了段的概念:内存
一个物理地址由段地址和偏移地址构成,即物理地址=段地址*16 + 偏移地址编译器
也能够说段地址左移4位,而后咱们能够推出偏移地址最大为2的16次方,即16Kb.asm
这里咱们要强调一个概念:编译
CPU是死的,一点都不智能,对于它自己而言,并不知道什么段的概念,段只是用来让咱们编程者使用的,咱们能够本身定义一个段的开始(定义CS或者DS),而后利用偏移地址灵活执行咱们写的指令,这样咱们就能够避免指令在内存空间的互相掩盖。
8086CPU不支持将一个数据直接写到段寄存器中去。
8086的栈操做是以字为单位的,这里咱们仍是要强调一个概念:
CPU是死的,它才不知道栈的概念呢,栈是咱们编程者本身在数据段里开辟,而后咱们用pop,push汇编指令操做,一切都是咱们编程者操做出来的。
CPU是如何知道栈的地址呢?:
CPU才不会知道呢,是咱们编程者本身首先定义好了一个栈段,而后咱们将这个栈段地址赋值到SS栈段寄存器中去,同时初始化SP寄存器。这样之后咱们pop或者push一个字时,sp加2或者减2。仍是那句话,都是咱们编程者实现栈的功能,让SS和SP永远指向栈顶。
只有bx,si,di,bp这四个寄存器能够进行内存单元寻址的,即[bx]这样语法操做的,其中bx,bp这两个寄存器不能同时出现,如[bx,bi],还有si,di这两个寄存器也是不能同时出现的。
bp寄存器隐形的段地址是ss。如咱们这样操做[ba],那么是经过SS段地址寻址内存单元的。
寄存器寻址几种方式:
1,直接寻址:[idata] idata 为当即数
2,寄存器间接寻址: [bx] , 默认段地址是DS
3,寄存器相对寻址:[bx+idata] ,默认段地址是DS
4,基址变址寻址:[bx+si], 默认段地址DS
5,相对基址变址寻址:[bx+si+idata], SA是DS
指令要处理的数据长度问题:
对于这个问题,咱们要根据编程者本身的选择的编译器而定,像咱们在windows下用的都是Masm风格的汇编编程,在linux上则是使用AT&T风格的。
这里是就masm风格而言,当咱们操做一个寄存器时,咱们根据寄存器的长度来肯定数据的长度,好比:
mov ax, [0]; 这里咱们就是要操做的数据长度是16位的。
可是当没有寄存器的时候,咱们就要经过标记符来肯定了。格式以下:
操做符 X ptr data, data; 这里X ptr依据(X可使word或者byte)来指定操做数据长度。
像push和pop就不须要指定了,他们两默认的是一个字。
div除法指令:被除数通常默认在AX或者BX中,或者就是32位的存储在AX,BX中,而后除完以后,余数在DX中,商在AX中
伪指令:
db:定义一个字节
dw:定义一个字
dd:double defined word 定义两个字节
dup:与db,dw,dd配合使用,表示复制的意思,好比: db 3 dup(0);
转移指令:
修改CS,IP或者仅仅修改IP的指令统称为转移指令,好比:
jmp data,只修改ip
jmp SA:EA 修改cs和IP
offset操做符:
获取一个标号的偏移地址,好比:
start:
mov ....
s:
mov ax, offset s; 此时至关于(mov ax, 1)
jmp指令:
jmp idata; jmp sa:ea; jmp short 标号(在段内短跳转);jmp far ptr 标号(段间跳转);jmp reg; jmp word ptr 内存单元地址(这里是将那个内存单元里的值给IP,段内转移); jmp dword ptr 内存单元地址(段间跳转,之内存单元地址所存的两个字的高地址为段地址,低地址为偏移地址);
jcxz指令:
当cx=0 跳转
loop指令:
至关于执行cx自减一,并前cx不等于0就跳转,跳转位移是8位,也就是说偏移地址在-128~127之间。
ret 指令:
有两条指令:ret,retf指令
ret指令至关于pop IP
retf 至关于连续执行 pop IP; pop CS 两条指令
call指令:
格式以下:
call 标号; 将当前IP压栈,而后跳到标号处执行(改变IP值)
call far ptr 标号; 段间转移
call reg(16位); 跳到IP=寄存器中的内容
call word ptr 内存单元地址; 跳到内存单元给定的值
call dword ptr 内存单元地址; 至关于执行:push CS; push IP; jmp dword ptr 内存单元地址;
call 和 ret通常配合使用,至关于调用了一个子函数。
mul乘法指令:
和div同样,用到AX,DX寄存器
标志寄存器:
里面存储的信息能够称为PSW(程序状态字),包括这些状态:
第六位,ZF:标明执行结果是否为0;
第二位, PF:奇偶标志位:执行结果中若是1的个数为偶数的话,则置1
第七位,SF:符号标志位:结果为负数则为1
第零位,CF:进位借位标志符:当最高有效位须要像更高位进位或者借位则置1(对于无符号位数)
第十一位,OF:溢出标志位(对于有符号位数)
第十位:DF:方向标志位:在串处理中,控制每次si,di的增减。DF为0,则每次si,di递减
串传送指令:
movsb;
至关于执行以下指令:mov es:[di], byte ptr ds:[si]; 若是DF=0 ,则后续为:inc si; inc di;
若是DF=1,则后续为: dec si; dec di;
movsw;
每次传送的是一个字
通常咱们传送一个串的话选择这样的命令:
rep movsb;
至关于:
s: movsb;
loop s; 依据CX来判断
pushf; popf; 将标志寄存器压栈或者弹出
条件转移指令:
je: equal,若是等于了,则ZF=0,依ZF做为判断 jne: no equal
jb: below,若是第一个数小于第二个数,则CF=1 jnb; no below
ja: above jna: