操作数就是指令或者程序的主要处理对象,只有很少数的指令不需要操作数,因为他们不具备数据处理功能,比如NOP空指令和HLT停机指令。
大多数指令的执行会涉及到操作数,所以指令中如何表达操作数或操作数所在位置是正确运用汇编指令的重要因素。
在指令中指令操作数或操作数存放位置的方法称为寻址方式。操作数的寻址方式是汇编语言进行程序设计的基础。
1. 立即数寻址方式
操作数作为指令的一部分直接写在指令中,这种操作数称为立即数,这种寻址方式称为立即数寻址方式。
立即数可以是8位,16位,32位,该数值紧跟在操作码之后,如果是16位或32位,按“高高低低”的方式存储。
如果有两个操作数,操作数不能作为第一个操作数,就像高级语言中常数不能放在等号左边一样。
2. 寄存器寻址方式
指令所要的操作数已经储存在寄存器中,或把目标操作数存入寄存器。把在指令中指出所使用的寄存器的寻址方式称为寄存器寻址方式。
指令中可以引用的寄存器及其符号如下:
8位寄存器有 AH AL BH BL CH CL DH DL
16位有 AX BX CX DX SI DI SP BP 和段寄存器
32位有EAX EBX ECX EDX ESI EDI ESP EBP
寄存器寻址方式也是简单便捷的寻址方式,源和目的操作数都可以是寄存器。
1) 源操作数是寄存器寻址方式
如 ADD VARD, EAX ADD VARW, AX ADD VARB, BH
其中VARD VARW VARB分别是双字 单字 字节的内存变量。
2) 目的操作数是寄存器的寻址方式
如 ADD BH, 78h ADD AX, 1234h MOV EBX, 12345678H等
3) 源和目的操作数都是寄存器寻址方式
如 MOV EAX, EBX MOV AX, BX MOV DH, BL
由于指令所需的操作数已存储在寄存器中,或操作的结果存入寄存器,这样,在指令执行过程中,会减少读写存储器单元的次数,所以,使用寄存器寻址方式的指令具有较快的执行速度,通常情况下,应该尽可能的充分利用寄存器。
3. 直接寻址方式
指令所需操作数已经存放在内存单元中,在指令中直接给出有效地址,这种寻址方式称为直接寻址方式。
在通常情况下,操作数存放在数据段中,所以其物理地址将由数据段寄存器DS和指令中给出的有效地址计算得出,但如果使用段超越前缀,操作数可以存放在其他段。
比如指令MOV BX, [1234H],会执行的操作是这样:
(1) 将寄存器DS的值向左移四位,然后加上1234H,求出实际的内存物理地址(为什么左移4位上一章《80x86CPU的内存管理》已经说过)
(2) 将实际地址中存放的值,放入寄存器BX中。
也可以在指令中采用段前缀方式指定使用其他的段,而不是默认段DS。
比如 MOV ES:[1000H], AX
直接寻址方式常用于处理内存单元的数据,其操作数是内存变量的值,该寻址方式可在64K字节的段内寻址。
注意:一定要带有[]号,否则会认为是立即数而不是内存单元。 实际运用时,一般不会直接写地址值,而是用内存变量名来表示,比如 MOV BX, VARW,其中的VARW就是内存字变量。
例子:
MOV AX, 1234H //立即数寻址
MOV AX, [1234H] //直接寻址
MOV AX, VARW //直接寻址
MOV AX, [VARW] //直接寻址
4. 间接寻址方式
操作数在内存中,操作数的有效地址用SI,DI,BX或BP寄存器保存着,计算公式如下:
PA = DS/ES/SS/CS * 16 + SI/DI/BX/BP
如果有效地址用SI/DI/BX的话,默认的段寄存器是DS(默认取数据段)
如果有效地址用BP的话,默认的段寄存器是SS(因为是栈操作嘛)
其实和直接寻址方式只有一点不同,直接寻址方式是给出的内存地址,或代表内存地址的变量,而间接寻址方式给出的是装有内存地址的寄存器。
5. 寄存器相对寻址方式
操作数在内存中,有效地址是一个基址寄存器(BX,BP)或变址寄存器(SI,DI)的内容和指令中的8位/16位偏移量之和。
如果有效地址用SI/DI/BX的话,默认的段寄存器是DS(默认取数据段)
如果有效地址用BP的话,默认的段寄存器是SS(因为是栈操作嘛)
指令中给出的8位/16位偏移量用补码表示,在计算有效地址时,如果偏移量是8位,则进行符号扩展成16位,当所得的有效地址超过0FFFFH,则取其64K的模。
比如 MOV BX, [SI+100H] 执行时是 DS * 16 + (SI + 100H)
6. 基址+变址寻址方式
操作数在内存中,其有效地址是一个基址寄存器(BX,BP)和一个变址寄存器(SI,DI)的内容的和,有效地址的计算公式为:
EA = BX/BP + SI/DI
其物理地址的计算公式仍然是:
PA = DS/SS * 16 + EA(当EA中含有BP的话段寄存器为SS,否则使用DS)
7. 相对基址 + 变址寻址方式
有效地址的公式为:
EA = BX/BP + SI/DI + 偏移量
物理地址的计算公式仍然是:
PA = DS/SS * 16 + EA
=================================
相对基址加变址寻址方式与其它寻址方式之间的变形关系
大多数指令的执行会涉及到操作数,所以指令中如何表达操作数或操作数所在位置是正确运用汇编指令的重要因素。
在指令中指令操作数或操作数存放位置的方法称为寻址方式。操作数的寻址方式是汇编语言进行程序设计的基础。
1. 立即数寻址方式
操作数作为指令的一部分直接写在指令中,这种操作数称为立即数,这种寻址方式称为立即数寻址方式。
立即数可以是8位,16位,32位,该数值紧跟在操作码之后,如果是16位或32位,按“高高低低”的方式存储。
如果有两个操作数,操作数不能作为第一个操作数,就像高级语言中常数不能放在等号左边一样。
2. 寄存器寻址方式
指令所要的操作数已经储存在寄存器中,或把目标操作数存入寄存器。把在指令中指出所使用的寄存器的寻址方式称为寄存器寻址方式。
指令中可以引用的寄存器及其符号如下:
8位寄存器有 AH AL BH BL CH CL DH DL
16位有 AX BX CX DX SI DI SP BP 和段寄存器
32位有EAX EBX ECX EDX ESI EDI ESP EBP
寄存器寻址方式也是简单便捷的寻址方式,源和目的操作数都可以是寄存器。
1) 源操作数是寄存器寻址方式
如 ADD VARD, EAX ADD VARW, AX ADD VARB, BH
其中VARD VARW VARB分别是双字 单字 字节的内存变量。
2) 目的操作数是寄存器的寻址方式
如 ADD BH, 78h ADD AX, 1234h MOV EBX, 12345678H等
3) 源和目的操作数都是寄存器寻址方式
如 MOV EAX, EBX MOV AX, BX MOV DH, BL
由于指令所需的操作数已存储在寄存器中,或操作的结果存入寄存器,这样,在指令执行过程中,会减少读写存储器单元的次数,所以,使用寄存器寻址方式的指令具有较快的执行速度,通常情况下,应该尽可能的充分利用寄存器。
3. 直接寻址方式
指令所需操作数已经存放在内存单元中,在指令中直接给出有效地址,这种寻址方式称为直接寻址方式。
在通常情况下,操作数存放在数据段中,所以其物理地址将由数据段寄存器DS和指令中给出的有效地址计算得出,但如果使用段超越前缀,操作数可以存放在其他段。
比如指令MOV BX, [1234H],会执行的操作是这样:
(1) 将寄存器DS的值向左移四位,然后加上1234H,求出实际的内存物理地址(为什么左移4位上一章《80x86CPU的内存管理》已经说过)
(2) 将实际地址中存放的值,放入寄存器BX中。
也可以在指令中采用段前缀方式指定使用其他的段,而不是默认段DS。
比如 MOV ES:[1000H], AX
直接寻址方式常用于处理内存单元的数据,其操作数是内存变量的值,该寻址方式可在64K字节的段内寻址。
注意:一定要带有[]号,否则会认为是立即数而不是内存单元。 实际运用时,一般不会直接写地址值,而是用内存变量名来表示,比如 MOV BX, VARW,其中的VARW就是内存字变量。
例子:
MOV AX, 1234H //立即数寻址
MOV AX, [1234H] //直接寻址
MOV AX, VARW //直接寻址
MOV AX, [VARW] //直接寻址
4. 间接寻址方式
操作数在内存中,操作数的有效地址用SI,DI,BX或BP寄存器保存着,计算公式如下:
PA = DS/ES/SS/CS * 16 + SI/DI/BX/BP
如果有效地址用SI/DI/BX的话,默认的段寄存器是DS(默认取数据段)
如果有效地址用BP的话,默认的段寄存器是SS(因为是栈操作嘛)
其实和直接寻址方式只有一点不同,直接寻址方式是给出的内存地址,或代表内存地址的变量,而间接寻址方式给出的是装有内存地址的寄存器。
5. 寄存器相对寻址方式
操作数在内存中,有效地址是一个基址寄存器(BX,BP)或变址寄存器(SI,DI)的内容和指令中的8位/16位偏移量之和。
如果有效地址用SI/DI/BX的话,默认的段寄存器是DS(默认取数据段)
如果有效地址用BP的话,默认的段寄存器是SS(因为是栈操作嘛)
指令中给出的8位/16位偏移量用补码表示,在计算有效地址时,如果偏移量是8位,则进行符号扩展成16位,当所得的有效地址超过0FFFFH,则取其64K的模。
比如 MOV BX, [SI+100H] 执行时是 DS * 16 + (SI + 100H)
6. 基址+变址寻址方式
操作数在内存中,其有效地址是一个基址寄存器(BX,BP)和一个变址寄存器(SI,DI)的内容的和,有效地址的计算公式为:
EA = BX/BP + SI/DI
其物理地址的计算公式仍然是:
PA = DS/SS * 16 + EA(当EA中含有BP的话段寄存器为SS,否则使用DS)
7. 相对基址 + 变址寻址方式
有效地址的公式为:
EA = BX/BP + SI/DI + 偏移量
物理地址的计算公式仍然是:
PA = DS/SS * 16 + EA
=================================
相对基址加变址寻址方式与其它寻址方式之间的变形关系
源操作数 |
指令的变形 |
源操作数的寻址方式 |
只有偏移量 |
MOV AX, [100H] |
直接寻址方式 |
只有一个寄存器 |
MOV AX, [BX] 或 MOV AX, [SI] |
寄存器间接寻址方式 |
有一个寄存器和偏移量 |
MOV AX, [BX+100H] 或 MOV AX, [SI+100H] |
寄存器相对寻址方式 |
有二个寄存器 |
MOV AX, [BX+SI] |
基址加变址寻址方式 |
有二个寄存器和偏移量 |
MOV AX, [BX+SI+100H] |
相对基址加变址寻址方式 |