cs:ip是指向程序执行的位置
code segment
ds 存储内存中取数据的地址,
data segment
ss:sp是指向堆栈的位置
stack segment
cx 里存储的是loop执行的标志:loop执行时,cx=cx-1,若此时cx里值为0,则跳出loop,否则继续loop
初始代码段长度存放在cx里
内存的地址 cs*10H + IP
ds*10H + [..]
ss*10H + sp :push后,sp=sp-2;pop后,sp=sp+2;栈为空时,指向栈底,否则总是指向栈顶
PS:
程序执行时,总是执行cs*10H+IP位置的代码;
类似mov ax, [..]时,总是从ds*10H+..位置处读内存,..可是是数,亦可以是bx寄存器,以bx寄存器里内容作为地址
push一次,sp=sp-2;
pop一次,sp=sp+2;
loop一次,cx=cx-1;根据cx是否为0决定循环是否继续
ds,cs,es,ss 不能直接mov值进去,需通过寄存器简介赋值
[..]中的只能用bx和bp寄存器做地址访问,且bx是默认以ds为基地址访问内存单元的,bp是以ss为基地址访问内存单元的
word ptr 和 byte ptr指明在没有寄存器参与的寻址单元中必要:
如:
mov byte ptr [1000H], 1 -- 2000:1000 01 FF FF ..
mov word ptr [1000H], 1 -- 2000:1000 01 00 FF..
push指令只进行字操作
除法指令div : 除数非8位和16位,存放在reg或者内存单元中
被除数:16位时,存放在ax中,32位时,高16位存放在dx中,低16位存放在ax中
结果:除数8位,AL存储商,AH存放余数;除数16位时,AX存储商,DX存储余数
div byte ptr ds:[0] -- (al) = (ax)/((ds)*16+0)商,(ah) = (ax)/((ds)*16+0)余数
div word ptr ds:[0] -- (ax) = ((dx)*10000H + (ax))/((ds)*16+0)商,(dx) = ((dx)*10000H + (ax))/((ds)*16+0)余数
jmp dword ptr 内存单元地址 -- (CS) = (内存单元地址+2)
(IP) = (内存单元地址)
jcxz --- if cx==0:ip = ip + 位移 else: ip不变,什么也不做,接着往下执行
ret和retf指令:
1.ret执行后:ip = (ss) * 10H + sp; sp = sp + 2 pop ip
2.retf执行后:ip = (ss) * 10H + sp; sp = sp + 2; cs = (ss) * 10H + sp; sp = sp+2 pop ip; pop cs
call指令:
call执行执行后,即先执行再压栈,ip或cs和ip压入栈中:sp = sp - 2; ((ss) * 10H + sp) = ip
call far ptr 标号:--ip指向下一条指令,执行完call指令后,push cs; push ip。
call ax/bx.. -- push ip;jmp ax--ip = (ax)
call word ptr -- push ip; jmp word ptr -- IP = 。。
call dword ptr -- push cs;push ip; jmp dword ptr .. cs高位,ip低位
汇编具有子程序的源程序框架:
assume cs:code
code segment
main:
...
call sub1
...
mov ax, 4c00H
int 21H
sub1:
...
...
call sub2
...
ret
sub2:
...
ret
code ends
end main
mul指令: mul 内存单元
乘数:8位存al,16位存ax
结果:8位乘数存ax,16位乘数高16存dx,低16存ax
mul byte ptr ds:[0] -- ax = al * (ds*10H + 0)
mul word ptr [bx + si + 8] -- ax 存低16位,dx存高16位
adc是对add的功能扩充:当加法位超过16位时
1EF000H + 201000H
mov ax, 001EH
mov bx, 0F000H
add bx, 1000H bx + 1000H
adc ax, 0020H ax + 0020H + CF(进位值) 对应sbb就是借位值sbb bx, 0020H -- bx - 0020H - CF
cmp指令:cmp ax, bx
ax = bx -- zf = 1
ax != bx -- zf = 0
ax < bx -- cf = 1
ax >= bx -- cf =0
ax > bx -- cf = 0 && zf =0
ax <= bx -- cf = 1 && zf = 1
和cmp搭配使用的指令
zf = 1 je equal
zf = 0 jne not equal
cf = 1 jb below
cf = 0 jnb not below
zf = 0 && cf = 0 ja above
zf = 1 && cf = 1 jna not above
cld df = 0正
tld df = 1反
将ds:si指向的内容送入es:di指向的内存中
movsb指令:df = 0 -- si = si + 1, di = di + 1
df = 1 -- si = si - 1, di = di - 1
movsw : df = 0 -- si = si + 2, di = di + 2
df = 1 -- si = si - 2, di = di - 2
rep movsb -- 根据cx进行的循环传送
中断:
8位(4字节)的中断类型码存储中断处理程序的入口地址8086cpu 0000:0000~0000:03FF,高地址字存放段地址(CS),低地址字存放偏移地址(IP)
中断过程:(机器自动完成)
1.取得中断类型码,即中断处理程序的cs:ip
2.标志寄存器的值入栈,因为中断过程中要改变标志寄存器的值
3.设置标志寄存器的第8位TF和第9为IF的值为0
4.CS的内容入栈
5.IP的内容入栈
6.中断类型码*4 + 2字单元读CS,中断类型码*4字单元读ip
中断入栈顺序:标志寄存器、cs、ip
iret 对比 retf
pop IP pop IP
pop CS pos CS
popf
int n中断处理过程(自动完成):
1.取中断类型码n;
2.标志寄存器入栈,IF=0,TF=0
3.cs,ip入栈
4.ip=n*4,cs=n*4+2
code segment
ds 存储内存中取数据的地址,
data segment
ss:sp是指向堆栈的位置
stack segment
cx 里存储的是loop执行的标志:loop执行时,cx=cx-1,若此时cx里值为0,则跳出loop,否则继续loop
初始代码段长度存放在cx里
内存的地址 cs*10H + IP
ds*10H + [..]
ss*10H + sp :push后,sp=sp-2;pop后,sp=sp+2;栈为空时,指向栈底,否则总是指向栈顶
PS:
程序执行时,总是执行cs*10H+IP位置的代码;
类似mov ax, [..]时,总是从ds*10H+..位置处读内存,..可是是数,亦可以是bx寄存器,以bx寄存器里内容作为地址
push一次,sp=sp-2;
pop一次,sp=sp+2;
loop一次,cx=cx-1;根据cx是否为0决定循环是否继续
ds,cs,es,ss 不能直接mov值进去,需通过寄存器简介赋值
[..]中的只能用bx和bp寄存器做地址访问,且bx是默认以ds为基地址访问内存单元的,bp是以ss为基地址访问内存单元的
word ptr 和 byte ptr指明在没有寄存器参与的寻址单元中必要:
如:
mov byte ptr [1000H], 1 -- 2000:1000 01 FF FF ..
mov word ptr [1000H], 1 -- 2000:1000 01 00 FF..
push指令只进行字操作
除法指令div : 除数非8位和16位,存放在reg或者内存单元中
被除数:16位时,存放在ax中,32位时,高16位存放在dx中,低16位存放在ax中
结果:除数8位,AL存储商,AH存放余数;除数16位时,AX存储商,DX存储余数
div byte ptr ds:[0] -- (al) = (ax)/((ds)*16+0)商,(ah) = (ax)/((ds)*16+0)余数
div word ptr ds:[0] -- (ax) = ((dx)*10000H + (ax))/((ds)*16+0)商,(dx) = ((dx)*10000H + (ax))/((ds)*16+0)余数
jmp dword ptr 内存单元地址 -- (CS) = (内存单元地址+2)
(IP) = (内存单元地址)
jcxz --- if cx==0:ip = ip + 位移 else: ip不变,什么也不做,接着往下执行
ret和retf指令:
1.ret执行后:ip = (ss) * 10H + sp; sp = sp + 2 pop ip
2.retf执行后:ip = (ss) * 10H + sp; sp = sp + 2; cs = (ss) * 10H + sp; sp = sp+2 pop ip; pop cs
call指令:
call执行执行后,即先执行再压栈,ip或cs和ip压入栈中:sp = sp - 2; ((ss) * 10H + sp) = ip
call far ptr 标号:--ip指向下一条指令,执行完call指令后,push cs; push ip。
call ax/bx.. -- push ip;jmp ax--ip = (ax)
call word ptr -- push ip; jmp word ptr -- IP = 。。
call dword ptr -- push cs;push ip; jmp dword ptr .. cs高位,ip低位
汇编具有子程序的源程序框架:
assume cs:code
code segment
main:
...
call sub1
...
mov ax, 4c00H
int 21H
sub1:
...
...
call sub2
...
ret
sub2:
...
ret
code ends
end main
mul指令: mul 内存单元
乘数:8位存al,16位存ax
结果:8位乘数存ax,16位乘数高16存dx,低16存ax
mul byte ptr ds:[0] -- ax = al * (ds*10H + 0)
mul word ptr [bx + si + 8] -- ax 存低16位,dx存高16位
adc是对add的功能扩充:当加法位超过16位时
1EF000H + 201000H
mov ax, 001EH
mov bx, 0F000H
add bx, 1000H bx + 1000H
adc ax, 0020H ax + 0020H + CF(进位值) 对应sbb就是借位值sbb bx, 0020H -- bx - 0020H - CF
cmp指令:cmp ax, bx
ax = bx -- zf = 1
ax != bx -- zf = 0
ax < bx -- cf = 1
ax >= bx -- cf =0
ax > bx -- cf = 0 && zf =0
ax <= bx -- cf = 1 && zf = 1
和cmp搭配使用的指令
zf = 1 je equal
zf = 0 jne not equal
cf = 1 jb below
cf = 0 jnb not below
zf = 0 && cf = 0 ja above
zf = 1 && cf = 1 jna not above
cld df = 0正
tld df = 1反
将ds:si指向的内容送入es:di指向的内存中
movsb指令:df = 0 -- si = si + 1, di = di + 1
df = 1 -- si = si - 1, di = di - 1
movsw : df = 0 -- si = si + 2, di = di + 2
df = 1 -- si = si - 2, di = di - 2
rep movsb -- 根据cx进行的循环传送
中断:
8位(4字节)的中断类型码存储中断处理程序的入口地址8086cpu 0000:0000~0000:03FF,高地址字存放段地址(CS),低地址字存放偏移地址(IP)
中断过程:(机器自动完成)
1.取得中断类型码,即中断处理程序的cs:ip
2.标志寄存器的值入栈,因为中断过程中要改变标志寄存器的值
3.设置标志寄存器的第8位TF和第9为IF的值为0
4.CS的内容入栈
5.IP的内容入栈
6.中断类型码*4 + 2字单元读CS,中断类型码*4字单元读ip
中断入栈顺序:标志寄存器、cs、ip
iret 对比 retf
pop IP pop IP
pop CS pos CS
popf
int n中断处理过程(自动完成):
1.取中断类型码n;
2.标志寄存器入栈,IF=0,TF=0
3.cs,ip入栈
4.ip=n*4,cs=n*4+2