汇编语言之寻址方式

来源:互联网 发布:小猪微电商系统源码 编辑:程序博客网 时间:2024/06/06 13:11

1 固定寻址(inherent addressing )

特定的单操作数指令,操作数隐含在操作码中,在固定寻址的指令中,操作数被隐含在指令中,不需要执行总线周期,执行速度快

例子:

1.1 CBW命令,将AL中的符号位扩展到AH中,形成16位的操作数。比如AL中的符号位是1,则执行CBW命令后,AH则变成FF,如果符号位是0,则AH则变成00

1.2 PUSH AX ,源操作数是寄存器AX,目的操作数为堆栈顶部,将AX寄存器中的内容压入堆栈

1.3 CWDE命令,是32位汇编指令,将AX中的符号位扩展到EAX的高位。

 

2  立即数寻址 (immediate addressing)

立即数寻址中,操作数包含在指令中,作为指令的一部分。特点:执行速度快,主要给寄存器赋值。同样不需要执行总线周期。

例子:

2.1 mov ax,14 ;主要给寄存器赋值,不能直接给段寄存器赋值,如不能mov ds/es/ss/cs ,立即数,会报错

 

3 寄存器寻址(register addressing)

说白了,就是操作数在寄存器中,直接去寄存器中寻找操作数。

例子:

3.1 mov ax,bx ;两个操作数都是寄存器寻址,

3.2 mov [1234h],ax ; 将AX寄存器中的值给地址1234处,当然段地址在DS中,可以用debug做实验验证下,如下:

运行-debug

-r 查看寄存器中的值

-a 编辑汇编命令

输入mov ax,12

mov [1234],ax,

 

然后查看1234处的指令

-d ds:1234  ;验证此时的值

然后运行两次 -p命令,

然后执行-d ds:1234命令,可以看到1234处的值变了

 

4  存储器寻址(momory addressing)

就是操作数存放在存储器中,用存储器寻址的指令,操作数一定在数据段、堆栈段、附加段中的主存储器中,指令中一定包含有存储器单元的地址或产生存储器单元地址的

信息,执行指令时,CPU先根据指令提供的地址信息,计算出偏移地址,用地址产生器产生出直接访问的内存地址,再从内存中取到操作数,执行规定的操作。

注意点:

1 可以采用段跨越前缀的方式来改变系统指定的默认段,(有的人叫段超越),默认的是DS段

2 串处理指令必须用ES段

3 栈操作指令必须用SS段

4 指令必须在CS中

 

储存器的地址是 段基地址偏移4位+偏移地址 ,由于偏移地址是16位的,所以2的16次方是64K,所以每个段的最大长度为64K 。存储器寻址方式如下:

4.1 直接寻址方式(direct addressing)

例子:

mov al,[2000] ;源操作数是直接寻址,目的操作数是寄存器存执,指令执行结果是将DS段中的偏移地址为2000的字节单元传送到AL中

mov ax,[2000] ; 唯一与上一条不同的是将字单元传送到AX中

mov ax ,es:[2000] ;段超越

mov dword ptr [1234] ,eax ;将EAX中的32位双字数据传送到内存中,目的操作数采用的存储器存执,源操作数采用寄存器存执。

4.2 寄存器间接寻址方式(register indirect addressing)

指操作数的偏移地址存放在制定的寄存器中,寄存器作为指针指向内存单元,而操作数在存储器中,这样的寄存器称为间址寄存器

在8086CPU中,只能使用BX,BP,SI ,DI 四个寄存器来充当存储器地址来进行寻址。BX,BP作为基址寄存器,SI,DI变址寄存器

当BX,SI,DI作为间址寄存器时,默认段寄存器在DS中,BP作为间址寄存器时,默认段寄存器为SS。

当然可以采用段超越改变段地址。

 

4.3 寄存器相对寻址方式(register relative addrssing)

与寄存器间接寻址方式类似,但不同的是,指令中还需要指定一个位移量,对于16位系统来说,位移量是8位或16位,对于32系统来说,位移量是

8位或32位的位移量,位移量是一个带符号的整数。

 

mov ax,10h[si]  ;等值与mov ax,[si+10h]

 

4.4 基址变址寻址方式(based indexed addressing)

操作数的偏移地址一部分在基址寄存器,一部分在变址寄存器,基址寄存器的内容加上变址寄存器的内容就是操作数的偏移地址,

例子:

mov ax,[bx][si] 等价于mov ax,[bx+si]

4.5 相对基址变址寻址方式(relative based indexed addressing)

带位移量的基址变址寻址方式称为基址 变址寻址方式。

例子:

mov ax,100[bx][si]  ;段地址再DS中

mov ax,100[bp][si] ; 段地址再SS中

 

4.6 比例变址寻址方式(scaled indexed addressing)

只有在32位及以后的80X86系统中使用,暂不介绍

 

5 I/O地址寻址(

分为直接端口寻址和间接端口寻址

5.1 direct i/o port addressing

用00h-ffh表示最低的0-255个8位的I/O端口地址,就可以直接进行I/O端口寻址,则可以寻址256个。

in al,80h;将80h端口的数据输入到AL寄存器中

in ax,80h;将80H端口的数据输入到AX寄存器中。

out 80h,AL;字节输出指令,将AL寄存器的内容输入到80H端口

 

5.2 indirect i/o port addressing

如果端口大于256个,则可以寻址65536个端口,必须使用间接寻址,先把0000H-FFFFH端口号存放到DX中,然后将DX寄存器中的值

mov ax,200h

out dx,al ; jiang AL输出到DX所指向的端口中

mov dx ,200h

in ax ,dx;将dx所指向的端口的一个字输入到AX寄存器中。

 

 

6  与转移地址有关的寻址

此类主要说的是转移指令,转移指令可以改变指令的执行顺序,进行跳转,简言之,就是改变CS和IP的值,从而改变下一条要执行的指令的物理地址

转移分为段内转移和段间转移,段内转移只是改变IP,并不改变CS,段间转移都改变。

段内转移和段间转移,都可以使用直接寻址和间接寻址

6.1 段内直接寻址 (intra segment indirect addressing)

jmp label ;label 为转移的地址符号,也称标号,

具体例子如下:

jmp short s

add ax,1

s:inc ax

当执行到jmp short s 后,会跳转到inc ax 执行。

6.2 段内间接寻址(intra segment indirect addressing)

转移的偏移地址是一个寄存器或时一个存储单元的内容,举例:

jmp bx ;BX内容传送到IP寄存器中,作为段内偏移地址

jmp word ptr [bp] ;BP指向的内存单元的一个字传送到IP,作为偏移地址

jmp word ptr[bp +val] ;BP+VAL指向的内存单元的一个字送给IP,作为偏移地址

 

z

6.3  段间直接寻址(inter segment direct addressing)

段间寻址和段内直接寻址类似,指令中直接给出转移地址,与段内寻址不同的是,段内直接寻址时,指令中提供了转移地址的段地址和偏移地址

将其中的段地址传送给CS,偏移地址传给IP. 完成程序控制间的段间转移

例子:jmp far ptr nseg ;在符号地址nseg之前加上表示段内转移的操作符far ptr

 

6.4 段间间接寻址(inter segment indirect addressing)

间接的获取转移的段地址和偏移地址,目的地址的段地址和偏移地址存放在内存中,这里存储单元的地址是由指令制定存储器寻址方式获取的

指令的格式:

jmp dword ptr [si] ;寻址方式为存储器寻址方式, dword ptr  为双字操作符,说明转移地址需取双字为段间转移地址,其中高字是段地址。转入CS,低字转入IP.

jmp dword ptr [addr]    ;在32位系统中,使用存储器寻址方式获取内存单元的48位指针,其中的低32位送EIP寄存器,高16位从CS寄存器,就能取得转移地址

0 0