8086的地址线是20位的,最大可寻址空间为1MB,8086将1MB存储器空间分为许多逻辑段,每个段最大限制为64KB。段地址必须是模16地址❗,即xxxx0H形式,省略低四位的0,段地址可以用16位数据表示。
段内偏移地址:说明主存单元距离段起始位置的偏移量,限定每段不超过64KB,因此偏移地址也可以用16位数据表示。
mov al,05h
mov ax,bx
mov ax,[2000h]
mov ax,[bx/si/di]
mov ax,[bx/bp/si/di + 06h] ;bp默认ss,其他默认ds
mov ax,[bx/bp+si/di];bx和bp分别对应ds和ss
mov ax,[bx/bp+si/di+06h]
mov reg/mem,imm
mov reg/mem/seg,reg
mov reg/seg,mem
也就是说 不允许imm–>seg,mem–>mem,imm不能作为目的操作数
xchg reg,reg/mem ;reg<-->reg/mem
push r16/m16/seg ;r16:16位的寄存器,m16:16位的存储器单元。
;sp<-sp-2, ss:[sp]<-r16/m16/seg
pop r16/m16/seg ;r16:16位的寄存器,m16:16位的存储器单元。
;sp<-sp-2, ss:[sp]<-r16/m16/seg
lea r16, mem
mov bx, 0400h
mov si, 3ch
lea bx, [bx+si+0f62h] ;bx<-bx+si+0f62h=0400h+3ch+0f62h=139eh
BX将会得到主存单元的有效地址,而不是物理地址,也不是该单元的内容。
add reg,imm/reg/mem
add mem,imm/reg
也就是说,不能进行mem+mem,(减法其实也是一样的
mov ax,1111h
add ax,1111h
mov dx,1111h
adc dx,1111h ;结束后,DX.AX为所需值 假装有进位吧
mov ax,1111h
sub ax,1111h
mov dx,1111h
sbb dx,1111h ;完成后DX.AX即为目标值,假装这里有借位
乘法指令隐含使用操作数AX和DX,AL与r8/m8相乘,存入AX,AX与r16/m16相乘,存入DX.AX。
对OF,CF有定义,对其他无。如果高一半没有有效数值(对MUL指令来说高一半为0,对IMUL指令来说高一半是低一半的符号扩展),则OF=CF=0,否则OF=CF=1。
除法指令隐含使用DX,AX作为一个操作数,被除数哦,AX除以r8/m8,8位商和余数分别存存AL、AH。DX.AX除以r16/m16,16位商和余数分别存AX,DX
对于无符号数据:零位扩展,8086没有设计指令,需要时可以直接对高位赋0
对于有符号数据:符号扩展
and reg,imm/reg/mem
and mem,imm/reg
jcc label
助记符 | 标志位 | 含义 |
---|---|---|
JZ/JE | ZF=1 | 等于0(and)/相等(cmp)跳转 |
JNZ/JNE | ZF=0 | 不等于0/不相等跳转 |
JS | SF=1 | 符号为负跳转 |
JNS | SF=0 | 符号为正跳转 |
JP/JPE(even) | PF=1 | "1"的个数为偶数跳转 |
JNP/JPO(odd) | PF=0 | "1"的个数为奇数跳转 |
JO | OF=1 | 溢出跳转 |
JNO | OF=0 | 无溢出跳转 |
JC/JB/JNAE | CF=1 | 进位/低于/不高于等于跳转 |
JNC/JNB/JAE | CF=0 | 无进位/不低于/高于等于跳转 |
JBE/JNA | CF=1 或则 ZF=1 | 低于等于/不高于跳转 |
JNBE/JA | CF=0 并且 ZF=0 | 不低于等于/高于跳转 |
JL/JNGE | SF≠OF | 小于/不大于等于跳转 |
JNL/JGE | SF=OF | 不小于/大于等于跳转 |
JLE/JNG | SF≠OF 或则 ZF=1 | 小于等于/不大于跳转 |
JNLE/JG | SF=OF 或则 ZF=0 | 不小于等于/大于跳转 |
RET:无参数段内返回
RET i16:有参数段内返回,ip<–ss:[sp],sp<–sp+2,sp<–sp+i16
.model small
.stack
.data
...
.code
.startup ;程序起始点,并设置DS和SS内容
... ;主程序代码
.exit 0 ;程序终止点,返回dos
... ;子程序代码
end ;汇编结束
.model small
.stack
.data
...
.code
START:mov ax,@data ;程序起始点,并设置DS和SS内容
mov ds,ax
... ;主程序代码
mov ax,4c00h ;程序终止点,返回dos
int 21h
... ;子程序代码
end start ;汇编结束
编辑、编译、连接
其他细节的好像没必要知道
org 100h ;从100h开始安排数据或程序
org $+10 ;使偏移地址加10,即跳过10字节空间
判断的条件是各种指令,如CMP、TEST等执行后形成的状态标志;双分支体中第1个分支体后一定要有一个JMP指令跳到第2个分支体后;如何实现多分支体
循环指令LOOP;串操作指令中的串寻址方式
movsb ;字节传送 es:[di]<-ds:[si] di++
movsw ;字传送 di+=2
stosb ;字节 存储 es:[di]<-al di++
stosw
lodsb ;字节 读取 al<-ds:[si] di++
lodsw
8
rep ;每执行一次串指令,cs--,直到cx=0,重复执行结束
cmpsb ;字节串比较 ds:[si]-es:[di]
cmpsw ;同
;源操作数减去目的操作数
scasb ;al-es:[di]
scasw ;ax-es:[di]
子程序的常见格式;子程序调用的三种参数传递方式;子程序如何保护寄存器的值;栈平衡的含义
实方式下,32位80x86cpu只能寻址1MB物理存储器空间,分段最大是64KB,32位80x86CPU可以使用32位寄存器和32位操作数,也可以采用32位的寻址方式。
不但具有段式存储管理功能,还提供页式存储管理功能,可以更好的支持虚拟存储器,在保护方式下,32位CPU才能发挥其全部功能,可以使用全部32条地址,使微处理器可寻址的物理存储器达到4GB。
在虚拟8086方式下,段寄存器的使用与实方式一样,左移4位加16位偏移量得到20位地址。如果采用分页存储管理,则在8086方式下,任务的1MB地址空间可以转移到4GB物理地址的任何位置。
mov eax,44332211h
mov eax,ebx
mov eax,[1234h]
mov eax,[ebx]
mov eax,[ebx+80h]
mov eax,[ebx+esi]
mov eax,[ebx+esi+80h]
mov eax,[esi*2]
mov eax,[ebx+esi*4]
mov eax,[ebx+esi*8+80h]
在C/C++语言中直接使用汇编语言语句
asm 操作码 操作数;
①两种语言分别编写独立的程序模块,分别产生目标代码OBJ文件,然后进行连接,形成一个完整的程序;
②模块连接的约定规则
③参数传递是关键