欢迎光临散文网 会员登陆 & 注册

汇编语言之寻址方式(超详细~)

2022-06-24 14:05 作者:补给站Linux内核  | 我要投稿

1 固定寻址(inherent addressing )

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

例子:

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

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

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

2  立即数寻址 (immediate addressing)

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

例子:

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

3 寄存器寻址(register addressing)

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

例子:

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

  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处的值变了


【文章福利】小编推荐自己的Linux内核技术交流群:【891587639】整理了一些个人觉得比较好的学习书籍、视频资料共享在群文件里面,有需要的可以自行添加哦!!!(含视频教程、电子书、实战项目及代码)    


4  存储器寻址(momory addressing)

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

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

  • 注意点:

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

  2. 串处理指令必须用ES段

  3. 栈操作指令必须用SS段

  4. 指令必须在CS中

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

4.1 直接寻址方式(direct addressing)

例子:

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

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

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

  4. 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

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

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

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

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

5.2 indirect i/o port addressing

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

  2. mov ax,200h

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

  4. mov dx ,200h

  5. 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,作为偏移地址

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寄存器,就能取得转移地址



汇编语言之寻址方式(超详细~)的评论 (共 条)

分享到微博请遵守国家法律