汇编的8种寻址方式,以及2个默认段寄存器
16位CPU所含有的寄存器有(见图2.1中16位寄存器部分):
4个数据寄存器(AX、BX、CX和DX)
2个变址和指针寄存器(SI和DI) 2个指针寄存器(SP和BP) ,32位CPU增加2个16位的段寄存器:FS和GS。
4个段寄存器(ES、CS、SS和DS)
1个指令指针寄存器(IP) 1个标志寄存器(Flags)
一共14个寄存器,或者16个
16位CPU内部有20根地址线,其编码区间为:0000H~FFFFFH,所以,它可直接访问的物理空间为1M(220)字节。
如果用16位寄存器来访问内存的话,则只能访问内存的最低端的64K,其它的内存将无法访问。为了能用16位寄存器来有效地访问1M的存储空间,16位CPU采用了内存分段的管理模式,并引用段寄存器的概念。
个人猜测:堆栈有1M的限制,是不是因为这个历史原因?
物理地址PA=段地址×16 + 偏移量(Offset)
有效地址EA=Effective Address(段内偏移)
CS:IP 段寄存器CS指向存放程序的内存段,IP是用来存放下条待执行的指令在该段的偏移量,把它们合在一起可在该内存段内取到下次要执行的指令。
SS:SP 段寄存器SS指向用于堆栈的内存段,SP是用来指向该堆栈的栈顶,把它们合在一起可访问栈顶单元。另外,当偏移量用到了指针寄存器BP,则其缺省的段寄存器也是SS,并且用BP可访问整个堆栈,不仅仅是只访问栈顶。
DS:ALL 段寄存器DS指向数据段,ES指向附加段,在存取操作数时,二者之一和一个偏移量合并就可得到存储单元的物理地址。该偏移量可以是具体数值、符号地址和指针寄存器的值等之一,具体情况将由指令的寻址方式来决定。
ES:DI 在进行串操作时,其目的地址的段寄存器规定为ES
总结:程序频繁访问的数据段用DS来指向,不太经常访问的数据段可用ES、FS和GS等来指向。
1.立即寻址方式 MOV AH, 80H(直接给寄存器赋值)
2. 寄存器寻址方式(源或者目的有一个是寄存器)
2.1) 源操作数是寄存器寻址方式
如:ADD VARD, EAX ADD VARW, AX MOV VARB, BH等。
其中:VARD、VARW和VARB是双字,字和字节类型的内存变量。
2.2) 目的操作数是寄存器寻址方式
如:ADD BH, 78h ADD AX, 1234h MOV EBX, 12345678H等。
2.3) 源和目的操作数都是寄存器寻址方式
如:MOV EAX, EBX MOV AX, BX MOV DH, BL等。
3. 直接寻址方式(地址值在括号里)
MOV BX, [1234H] (默认使用DS)
MOV ES:[1000H], AX
4. 寄存器间接寻址方式(寄存器在括号里)
MOV BX,[DI]
操作数的有效地址用SI、DI、BX和BP等四个寄存器之一来指定,称这种寻址方式为寄存器间接寻址方式。
若有效地址用SI、DI和BX来指定,则其缺省的段寄存器为DS;
若有效地址用BP来指定,则其缺省的段寄存器为SS(即:堆栈段)。
5. 寄存器相对寻址方式(一个寄存器和一个立即数在括号里,并且还要计算)
MOV BX, [SI+100H]
6. 基址加变址寻址方式(两个寄存器在括号里,并且还要计算)
MOV BX, [BX+SI]
7. 相对基址加变址寻址方式(两个寄存器在括号里和一个立即数在括号里,并且还要计算)
MOV AX, [BX+SI+200H]
几个例子:
例子1. MOV BX, [SI+100H]
寻址路线为:
PA=(DS)*16+(SI)+100H
例子2. MOV BX, [BX+SI]
寻址路线为:
PA=(DS)*16+=(BX)+(SI)
例子3. MOV AX, [BX+SI+200H]
寻址路线为:
PA=(DS)*16+(BX)+(SI)+200H
取数据的规则:高高低低
比如内存单元12445H的Byte值为15H,12446的Byte内容为27H,那么12445的Word值为2715H,而BX的值也是2715.
注:为了简化理解,低地址在上面,高地址在下面(所谓向下生长)。与堆栈模型一致,参考:
http://www.cnblogs.com/findumars/archive/2012/10/28/2743121.html
8. 32位地址的寻址方式
在用16位寄存器来访问存储单元时,只能使用基地址寄存器(BX和BP)和变址寄存器(SI和DI)来作为地址偏移量的一部分。
但在用32位寄存器寻址时,不存在上述限制:
32位基址寄存器是:EAX、EBX、ECX、EDX、ESI、EDI、EBP和ESP;
32位变址寄存器是:EAX、EBX、ECX、EDX、ESI、EDI和EBP(除ESP之外)。
计算公式:基址寄存器+变址寄存器+比例因子+偏移常量。
段寄存器的判断与使用:
1)地址中寄存器的书写顺序决定该寄存器是基址寄存器,还是变址寄存器,例如:
[EBX+EBP]中的EBX是基址寄存器,EBP是变址寄存器。
[EBP+EBX]中的EBP是基址寄存器,EBX是变址寄存器。
2)基址寄存器是EBP或ESP时,默认的段寄存器是SS,否则,默认的段寄存器是DS,例如:
MOV AX, [123456H] ;默认段寄存器DS
MOV EAX, [EBX+EBP] ;默认段寄存器DS
MOV EBX, [EAX+100H] ;默认段寄存器DS
MOV EBX, [EBP+EBX] ;默认段寄存器SS
MOV [ESP+EDX*2], AX ;默认段寄存器SS
MOV AX, [ESP] ;默认段寄存器SS
3)在指令中,如果使用段前缀的方式,那么,显式段寄存器优先。
MOV EDX, ES:[EAX*4+200H] ;显式段寄存器ES
MOV EBX, GS:[EAX+EDX*2+300H] ;显式段寄存器GS
为了明确指令中存储单元的属性,可把指令“MOV [BX], 1H”可改写成:
MOV byte ptr [BX], 1H 或 MOV word ptr [BX], 1H
一个字节的内容是该字节单元内存放的二进制信息;
一个字的内容是该字地址所指向的单元及其后继一个单元的内容拼接而成;
一个双字的内容是该字地址所指向的单元及其后继三个单元的内容拼接而成。