X86CPU的寻址方式大体可以分为3类:寄存器寻址,立即数寻址,内存寻址
内存寻址又可分为以下几类:直接寻址,基址寻址,变址寻址,基址变址寻址
寻址指的是CPU在寻找数的地址,这个数可以是源操作数,也可以是目的操作数,Intel的汇编语法是 (指令 目的操作数,源操作数)
##############################################################
寄存器寻址:指"数"就在寄存器中,直接从寄存器中拿数就可以了 mov ax, 0x19 mov dx, 0x18 mul dx 只要牵扯到寄存器的寻址,无论其是源操作数,还是目的操作数,都是寄存器寻址。又由于它们的源操作数是立即数,所以也是立即数寻址。
##############################################################
立即数寻址:立即数就是常数,为什么要叫立即数,CPU通过其他方式得到的数要么在内存中,要么在寄存器中,CPU想要得到该数就需要花费一些周期去内存或寄存器中取数,如果操作数直接出现在指令中,CPU直接就可以使用,为了突显“立即就能用”的高效率,所以叫立即数 mov ax, macro_selector mov ax, label_start 也是立即数寻址,macro_selector是个宏,label_start是个标号,这两个在编译阶段会转为数字,在最终的可执行文件中依然是立即数
##############################################################
直接寻址:直接寻址就是直接给出内存地址,CPU将会去这个内存地址取值作为操作数 mov ax, [0x1234] mov bx, [Fs:0x5678] 由于访问内存是用“段基址:段内偏移地址”的形式。默认的寄存器是Ds,所以第一条指令是到Ds:0x1234处取值,并将值送入ax寄存器中。第二条指令中由于使用了段跨越前缀Fs,所以段寄存器变成了Gs,所以第二条指令是到Gs:0x5678处取值,并将去到的值送入ax寄存器
##############################################################
基址寻址:以bx或bp作为基址,将基址与偏移量相加,得到的地址作为操作数的有效内存地址。基址寄存器只能是bx或bp,bx的默认寄存器是Ds,bp的默认寄存器是Ss mov ax, [bx+4]
##############################################################
变址寻址:变址寻址和基址寻址类似,只不过寄存器由bx,bp变成了si,di。 si(resource index):原索引寄存器 di(destination index):目的索引寄存器 这两个寄存器的默认段寄存器也是ds,变址寻址主要用于字符串搬运方面 mov [di], ax mov [si+0x1234], ax
##############################################################
基址变址寻址:基址变址寻址是基址寻址与变址寻址的结合,即基址寄存器bx或bp加一个变址寄存器si或di mov [bx+di], ax add [bp+si], ax 第一条指令的意思是将ax寄存器中的值送入以Ds为段基址,bx+di为偏移地址的内存,第二条指令的意思是将ax与[ds:bp+si]处的值相加后存入内存[ds:bp+si]