计算机地址与8086寻址方式以及32位处理器的寻址方式

来源:互联网 发布:交换机端口控制器 编辑:程序博客网 时间:2024/06/01 22:52

8086的16位处理器的寻址方式

寄存器寻址

操作的数位于寄存器中,可以从寄存器里取得。
mov ax,bxadd bx,0xf000inc dx

立即寻址

操作数在指令中直接给出。
add bx,0xf000;源操作数是立即寻址,目的操作数是寄存器寻址mov dx,label_a;label_a是标号,标号是数值的等价形式,代表了所在位置的汇编地址

以上两种寻址速度较快,但是 寄存器的数量有限,我们也不能总是提前知道操作数是多少,也就无法使用立即数。

内存寻址(用方括号括起来)

直接寻址

操作数是一个偏移地址。
mov ax,[0x5c0f]add word [0x0230],0x5000xor byte [es:label_b],0x05 ;es是段超越前缀

基址寻址

使用基址寄存器BX或BP提供偏移量。
mov [bx+buffer],dxadd byte [bx],0x55mov dx,[bp-2]

mov bx,buffermov cx,4lpinc:inc word [bx]add bx,2loop lpinc

变址寻址

使用变址寄存器(或称为索引寄存器)SI和DI提供偏移量。
mov [si],dxadd ax,[di]mov [si+0x100],aladd byte [di+label_a],0x80

基址变址寻址

使用基址寄存器(BX或BP)和变址寄存器(SI和DI)一起提供偏移量。
string db 'abcdefghijklmnopqrstuvwxyz'mov bx,string;数据首地址mov si,0;正向索引mov di,25;反向索引order:mov ah,[bx+si]mov al,[bx+di]mov [bx+si],almov [bx+di],ahinc sidec dicmp si,dijl order


地址

线性地址:线性地址空间中的一个地址,用来描述任务的地址空间。线性地址空间就是,一个总长为N的平坦(没有分段)的地址空间。
有效地址:偏移量。
逻辑地址:段地址和有效地址。
物理地址:内存中的真实地址。
当分页功能开启后,段部件产生地址对应着线性空间中的一个地址,即线性地址。该线性地址与指令中的偏移量一起形成逻辑地址,最后由页部件转换为物理地址。

32位处理器的寻址方式

在16位处理器上,指令中的操作数可以是 8位或16位的寄存器、指向8位或16位实际操作数的16位内存地址,以及8位或16的立即数。

指定有效地址可以使用 基址寄存器BX、BP,变址(索引)寄存器SI和DI,同时还可以加上一个8位或16位的偏移量,比如
mov ax,[bx]mov ax,[bx+si]mov ax,[bx+si+0x02]

以下是16位处理器的内存寻址方式示意图。从图中可以看出,允许使用基址寄存器BX或BP,同变址寄存器SI或者DI组合,再加上8位或16位偏移量来寻址内存操作数。

16位处理器的寻址方式本来就很复杂,当32位处理器出现后,寄存器和偏移地址的宽度都扩展了,相应地,要继续扩展原有的寻址方式。但是,原有的16位方案已经成型,再进行修补是非常困难的。一个可行的解决方案是,让16位指令和32位指令共用相同的指令码,但通过不同的指令前缀,结合处理器当前的运行状态来决定指令的寻址方式。

比如,当在16位模式时,如果没有指令前缀0x66,则认为指令是传统的16位寻址方式;若有前缀,则指令是新的32位寻址方式。当在32位模式时,如果没有指令前缀,则视为默认的32位寻址方式,否则就是传统的16位寻址方式。

在32位模式时,可以使用全部的32位通用寄存器作为基址寄存器,同时还可以加上除 ESP 之外的32位通用寄存器作为变址寄存器。变址寄存器允许乘以1、2、4、8作为比例因子。最后还允许加上一个8位或者32位的偏移量。

add eax,[0x2008]sub eax,[eax+0x08]mov ecx,[eax+ebx*8+0x02]

值得注意的是,在16位模式时,内存寻址方式的操作数不允许使用栈指针寄存器SP。因此,像这条指令就是不正确的:
mov ax,[sp]

但是在32位模式时,允许在内存操作数中使用栈指针寄存器ESP。因此,下面的指令形式是合法的:
mov eax,[esp]