写这个一方面是为了帮自己总结一下,同时也将自己学习的思路和大家分享交流一下,所以这不是教程,而且我也没那实力写教程,只是将个人感觉重要的总结一下,欢迎拍砖。
从放假到现在两个星期左右,由于还要看OpenGL和Java,而且假期效率不高,所以进度很慢只看完两章(整本书一共11章——),第一章主要是汇编语言概述和Intel系列CPU简介,第二章是8086/8088寻址方式和指令系统,这两章比较重要的就是七种基本寻址方式和指令系统,由于指令系统还有点没看完,所以这次主要写写8086/8088寻址方式。(书上说由于80x86系列的指令系统向上兼容,所以只介绍8086/8088的)
8086/8088 寻址系统:
所谓寻址,就是表示指令中操作数所在位置的方法,换句话说就是你换着花样传输给机器同一个数据,就比如某人向你问路,目的不变,但你可能有若干种方法告诉他怎么到达。汇编里一共有七种基本的寻址方式:立即寻址方式、寄存器寻址方式、直接寻址方式、寄存器间接寻址方式、寄存器相对寻址方式、基址加变址寻址方式和基址加变址相对寻址方式。
1.立即寻址方式
这种方式就是直接给出操作数,也就是直接给出值而不是值所在的地址,简单明了,但是指令的执行速度不是很快,因为需要访问存储器来获取操作数,同时这种直接给出的操作数也叫做立即数。
例子:MOV CX, 1423H
2.寄存器寻址方式
这种方式是将存储在CPU寄存器中的操作数读取到另一个寄存器,由于是直接访问寄存器,所以指令的执行速度要比立即寻址快得多
例子:MOV SI, AX
3.直接寻址方式
这种方式是操作数存储在数据段寄存器中,指令给出操作数在数据段寄存器DS里的偏移值(可直接给出,也可给出存储偏移值的寄存器),从而获得操作数。但是如果在指令中使用了段超越前缀,也就是指定了操作数存储的段寄存器,则给出的偏移值也是指定的段寄存器的。
例子:MOV AX, [1223H] 直接给出
MOV AX, CL 给出所在寄存器
MOV ES:[5634H], BL 使用段超越前缀
4.寄存器间接寻址方式
此方式与直接寻址类似,只是对存储偏移值和操作数的寄存器做了限定。七种偏移值存储在SI、DI、BX、BP中,在不使用段超越前缀的情况下,如果有效地址在BP中,则操作数存储在SS中,否则则存储在DS中。若使用了段超越前缀,则使用指定寄存器。
例子:MOV AX,SI 寄存器寻址
MOV AX,[SI] 寄存器间接寻址(注意写法,不要忘了中括号)
5.寄存器相对寻址方式
此方式及时获取相对某寄存器内某点的某个位置的操作数,也可以看成是先进行寄存器间接寻址,然后再相对此位置偏移一定长度,其对寄存器的限定和寄存器间接寻址是一样的。
例子:MOV AX,[SI+1431]
6.基址加变址寻址方式
此方式与寄存器相对寻址类似,只是第二次偏移的长度存储在某个寄存器中,在不使用段超越前缀的情况下,第一次偏移长度存储在BP、BX中,第二次存储在SI、DI中,同时和前面一样,若使用BP,则操作数存储在SS中,否则则在DS中。
例子:MOV BX,[BP+SI]
7.基址加变址相对寻址方式
这个方式没什么可说的,其实就是进行完基址加变址寻址后,在做一次偏移,偏移的长度则直接给出。
例子:MOV AX, [BX+DI+1423H]