赞
踩
AX
BX
CX
DX
通用寄存器指的是存放数据的数据寄存器
这四个寄存器有一个其他寄存器所没有的,因为他们可以分割成两个8位的寄存器
AX=AH+AL
BX=BH+BL
CX=CH+CL
DX=DH+DL
AX的高8位构成AH寄存器,AH的低8位构成Al寄存器
H代表high,L代表low
AX寄存器相当于一个箱子,箱子是有容量的,AX寄存器可以存放2byte数据,1byte=8bit,2byte=16bit,表示范围是0000000000000000~1111111111111111 0~FFFFH 0~65535
所以这四个寄存器也叫16位寄存器
我们研究的是8086CPU,比较古老了 ,为了兼容之前的8位寄存器,让以前的程序稍加修改,就可以运行在8086CPU上。
最小单位为字节,8个bit
CPU从内存中读取一个字节,8bit 字节型数据->存放在8位寄存器中,所以我们需要8位的寄存器,这也是AX寄存器为什么分为高8位和低8位的原因。
8086CPU有16根数据线,我们知道数据线的宽度决定了CPU一次性能够读取多少位的数据。
8086CPU一次性可以处理2中尺寸的数据:
字节型数据:1byte 8bit---->存放在8位寄存器中
字型数据:2byte 16bit----->存放在16位寄存器中
2个字节:一个是这个字型数据的高位字节(AH,BH,CH,DH),一个是这个字型数据的低位字节(AL.BL,CL,DL)
5到0005经过了编译过程,编译器在执行mov指令时,要保证了数据数据和寄存器之间的位数的一致性
mov指令就是将逗号右面的东西给逗号右面。
通过这些代码,我们应该了解到的是数据要和寄存器的位数保持一致性
8位寄存器给8位寄存器,8位数据给8位寄存器,16位数据给16位寄存器
mov ax,4E20H(H不输入到dosbox中,代表的是4位16进制数) #将4E20H存放到ax寄存器中,此时ax=4E20H
mov bx,ax #将ax=4E20H存放到bx中去,此时bx=4E20H
mov ch,bl #此时bx=4E20H,它的低8位是20H,bl=20H,所以此时ch=20,而cx=2000
mov cl,bh #此时bx=4E20H,它的高8位是4EH,bh=4EH,所以此时cl=4E,而cx=204E
mov dl,ch #此时cx=204EH,它的高8位为20H,ch=20H,所以dl=20H,而dx=0020H
mov ax,dx #此时dx=0020H,将dx存放到ax寄存器里,此时的ax=0020H
我们执行命令mov ax,bl会出现报错,因为bl位8位寄存器,而ax为16位寄存器
dosbox中的数据都是16进制,我们执行mov al,100,这里的100代表的是100H,100H超过了8位,还有mov al 0005,也会出现报错,因为0005H是16位数据,超过了8位
当超过寄存器的最大保存位时,就只能保存最大位,比如8位寄存器只能保存8位的16进制数,前面多余的不保存
加法指令add ax,8H指的是将8加到ax中去,在赋值给ax,即ax=ax+8
debug -a
mov ax,18H
mov ah,78H
add ax,8
8位运算:8位寄存器进行8位运算,保存8位数据
mov ax,0
mov ax,93H
add al,85H
当存储8位数据的时候,93H+85H=118H,但是寄存器只能存储8位数据,寄存器是互相独立的,al多的位也不会存放到ah寄存器中,e而是把1存到其他地方去了,所以ax=0018
16位运算:
mov ax,0
mov al,93H
add ax,85H
因为16位寄存器ax可以保存16位数据,所以118H可以被保存在ax寄存器中
寄存器是互相独立的,在他们运算的时候,是不会影响其他寄存器的,AL就是AL,AH就是AH,不会互相影响的。
写出每条指令执行后相关寄存器中的值
汇编指令里的H指的是16进制HEX
mov ax,62627 #这里存在一个陷阱,62627是10进制,转换为16进制为F4A3 ax=F4A3H
mov ah,31H #ax=31A3H
mov al,23H #ax=3123H
add ax,ax #ax=6246H
mov bx,826CH #bx=826CH
mov cx,ax #cx=6246H
mov ax,bx #ax=826CH
add ax,bx #ax=04D8H
mov al,bh #ax=0482H
mov ah,bl #ax=6C82H
add ah,ah #ax=D882H
add al,6 #ax=D888H
add al,al #ax=D810H
mov ax,cx #ax=6246H
只利用学过的add汇编指令,最多使用4条指令,编程计算2的4次方
mov ax,2
add ax,ax
add ax,ax
add ax,ax
因为10进制的16在16进制中表示位0010
在dosbox中,073F:0100,冒号左面的表示段地址,右面的表示偏移地址
段地址寄存器 | 偏移地址寄存器 |
---|---|
ds | sp |
es | bp |
ss | si |
cs | di |
dx 地址信息也可以当做一种数据 |
8086CPU有20根地址线(地址线举决定了CPU的寻址能力),但是寄存器是16位的寄存器,所以设计者给8086CPU加了一个地址加法器。
地址加法器是一种计算方式:段地址X16(10进制的16)+偏移地址=物理地址
段地址X16(10进制的16)=基础地址
段地址 偏移地址
F230H X 10H C8H =F23C8H
物理地址
不管怎么用段地址和偏移地址表示,只要是同一个物理地址,就是指的是一个地址
偏移地址的范围0000-FFFFH
1.段地址为0001H仅仅通过变化偏移地址,CPU的寻址范围为10H到1000FH
2.有一个数据存放在内存20000H的单元中,现给段地址为SA,若想用偏移地址寻找到此单元,则SA应该满足的条件是最小是1001H最大是2000H
SA*10H+0=20000H
SA*10H+FFFFH=20000H 解得SA为1000H,但是1000H10H+FFFFH=1FFFFH,这样是找不到20000H的,所以SA应该为1001H,1001H10H+FFFFH=2000FH,这样才把20000H包括进来。
提示:反过来思考一下,当段地址为多少的时候,CPU无论怎么改变偏移地址都无法找到20000H?
当CPU给的段地址为1000H时,是无法找到20000H这个地址的(这是个陷阱)
dosbox中:
u指令:将某个内存地址开始的字节全部当做是指令
d指令:将某个内存地址开始的字节全部当做是数据
IP寄存器和指令指针有关
CS寄存器是段地址寄存器
8086CPU中,在任何的时刻,CPU将cs:ip指向的内容全部当做指令来执行。
在内存中,指令和数据是没有区别的,都是以二进制保存的。CPU只有在工作的时候才将有的信息当做指令,有的信息当做数据。
CPU根据什么将内存中的信息当做指令?
CPU将CS:IP指向的内存单元中的内容当做指令
指令和数据在内存中有区别吗?
没有区别,二者都是以二进制的形式保存在内存中的
在CPU中的CS段地址寄存器和IP偏移地址寄存器组合的时候才会将其当做指令去执行的
CS IP决定了CPU从哪里开始读取指令
debug -u发现每条指令是具有长度的,不同的指令占有的字节是不同的
指令是具有长度的,一条指令是可以由多个字节构成的
1.CPU从cs:ip所指向的内存单元中读取指令,存放到指令缓存器中
2.IP=IP+所读指令的长度,从而指向下一条指令。
3.执行指令缓存器的内容,回到步骤1
debug -a
mov ax,1000H
mov bx,1000H
mov dl,10H
执行-r ,出现的指令有3个字节
IP现在为100,IP加上指令长度,指向下一条指令
-d 指令100指向的是B8
汇编指令jmp指令:转移指令,可以修改CS和IP这两个寄存器,决定了CPU从哪里读取指令
jmp 2000:0将2000给CS,0给IP
jmp寄存器
call指令:转移指令
mov ax,bx #将这条指令存放到指令缓存器中,IP改变一次,执行这条指令 ax=bx
sub ax,ax #将这条指令放入指令缓存器,IP改变一次,执行这条指令,ax=0
jmp aX #将这条指令存放到指令寄存器中去,ip改变一次,执行这条指令ip=0,再修改一次ip
最后ip的值为0
CPU总共修改了4次ip,ip最后的值为0
jmp寄存器
call指令:转移指令
mov ax,bx #将这条指令存放到指令缓存器中,IP改变一次,执行这条指令 ax=bx
sub ax,ax #将这条指令放入指令缓存器,IP改变一次,执行这条指令,ax=0
jmp aX #将这条指令存放到指令寄存器中去,ip改变一次,执行这条指令ip=0,再修改一次ip
最后ip的值为0
CPU总共修改了4次ip,ip最后的值为0
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。