本文共 2962 字,大约阅读时间需要 9 分钟。
---------------------------------------------------------------------------------------------------------------------
欢迎关注 [懒人漫说] 公众号,分享Java、Android、C/C++ 技术,
包括基础、自己遇到的问题解决过程。
当然如果关注并留言问题的话,我们力所能及的话会帮你解决并回复哟。我们和你一样,是正在成长的程序员,我们也会分享自己的成长路上的感想,希望可以和你一起努力成长。
X86汇编常见的寄存器
4个数据寄存器(EAX、EBX、ECX和EDX)
2个变址和指针寄存器(ESI和EDI) 2个指针寄存器(ESP和EBP) 6个段寄存器(ES、CS、SS、DS、FS和GS) 1个指令指针寄存器(EIP) 1个标志寄存器(EFlags) 数据寄存器 4个16位寄存器又可分割成8个独立的8位寄存器(AX:AH-AL、BX:BH-BL、CX:CH-CL、DX:DH-DL),每个寄存器都有自己的名称,可独立存取。程序员可利用数据寄存器的这种”可分可合”的特性,灵活地处理字/字节的信息。寄存器AX和AL通常称为累加器(Accumulator),用累加器进行的操作可能需要更少时间。累加器可用于乘、 除、输入/输出等操作,它们的使用频率很高; 寄存器BX称为基地址寄存器(Base Register)。主要用于存储内存中数据存放的基础位置.之后只需要知道偏移地址就可以知道内存实际地址. 寄存器CX称为计数寄存器(Count Register)。在循环和字符串操作时,要用它来控制循环次数;在位操作 中,当移多位时,要用CL来指明移位的位数;寄存器DX称为数据寄存器(Data Register)。在进行乘、除运算时,它可作为默认的操作数参与运算,也可用于存放I/O的端口地址。 在16位CPU中,AX、BX、CX和DX不能作为基址和变址寄存器来存放存储单元的地址, 在32位CPU中,其32位寄存器EAX、EBX、ECX和EDX不仅可传送数据、暂存数据保存算术逻辑运算结果,而且也可作为指针寄存器,所以,这些32位寄存器更具有通用性。 EAX 是"累加器"(accumulator), 它是很多加法乘法指令的缺省寄存器。 EBX是"基地址"(base)寄存器, 在内存寻址时存放基地址。 ECX 是计数器(counter), 是重复(REP)前缀指令和LOOP指令的内定计数器。 EDX则总是被用来放整数除法产生的余数。 EAX 是"累加器"(accumulator), 它是很多加法乘法指令的缺省寄存器。 ESI/EDI分别叫做"源/目标索引寄存器"(source/destination index)它们主要用于存放存储单元在段内的偏移量,用它们可实现多种存储器操作数的寻址方式,为以不同的地址形式访问存储单元提供方便。 3、指针寄存器 32位CPU有2个32位通用寄存器EBP和ESP。其低16位对应先前CPU中的SBP和SP,对低16位数据的存取,不影响高16位的数据。 寄存器EBP、ESP、BP和SP称为指针寄存器(Pointer Register),主要用于存放堆栈内存储单元的偏移量,用它们可实现多种存储器操作数的寻址方式,为以不同的地址形式访问存储单元提供方便。指针寄存器不可分割成8位寄存器。作为通用寄存器,也可存储算术逻辑运算的操作数和运算结果。 它们主要用于访问堆栈内的存储单元,并且规定: BP为基指针(Base Pointer)寄存器,用它可直接存取堆栈中的数据; SP为堆栈指针(Stack Pointer)寄存器,用它只可访问栈顶。 4、段寄存器 段寄存器是根据内存分段的管理模式而设置的。内存单元的物理地址由段寄存器的值和一个偏移量组合而成 的,这样可用两个较少位数的值组合成一个可访问较大物理空间的内存地址。 CPU内部的段寄存器: CS——代码段寄存器(Code Segment Register),其值为代码段的段值; DS——数据段寄存器(Data Segment Register),其值为数据段的段值; ES——附加段寄存器(Extra Segment Register),其值为附加数据段的段值; SS——堆栈段寄存器(Stack Segment Register),其值为堆栈段的段值; FS——附加段寄存器(Extra Segment Register),其值为附加数据段的段值; GS——附加段寄存器(Extra Segment Register),其值为附加数据段的段值。 写到这里要写一写内存的寻址方式了.我在这里只介绍间接寻址,相对寻址,基址变址寻址.如果没看懂的话,可以回去看一看前面写的各个寄存器的定义 4寄存器间接寻址 操作数在存储器中,操作数的有效地址在SI,DI,BX,BP这4个寄存器之一中。在不采用段前缀的情况下, 对于DI,SI,BX默认段为DS,而BP为SS。 eg. mov ah,[bx] ; mov ah,cs:[bx] ; 5 寄存器相对寻址 操作数在存储器中,操作数的有效地址是一个基址寄存器(BX,BP)或变址寄存器(SI,DI)的 内容加上8位或16位的位移之和。在指令中的8位和16位的常量采用补码表示,8位要被带 符号扩展为16位。 eg. mov ah,[bx+6] ;段址默认情况与寄存器间接寻址相同 6 基址加变址寻址 操作数在存储器中,操作数的有效地址是一个基址寄存器(BX,BP)加上变址寄存器(SI,DI)的 内容。如果有BP,则默认段址为SS,否则为DS. eg. mov ah,[bx+si] 7 相对基址加变址寻址 操作数在存储器中,操作数的有效地址是一个基址寄存器(BX,BP)和变址寄存器(SI,DI)的 内容加上8位或16位的位移之和。如果有BP,则默认段址为SS,否则为DS. eg. mov ax,[bx+di-2] mov ax,1234h[bx][di] 现在解释一下上面的定义 在8086CPU中,使用[]来表示寄存器间接寻址.但是只有bx、si、di、bp寄存器可以在中来进行内存单元的寻址; BX BP是基址地址(类型)的存储器,SI DI是偏移:因此我们可以得到地址 = 基址地址 + 偏移地址 同时由于某些奇怪的原因段寄存器被用到了,因此许多时候上面的段寄存器来定位储存位置.使用上是 段寄存器 : [...] 若有效地址用SI、DI和BX等之一来指定,则其缺省的段寄存器为DS;若有效地址用BP来指定,则其缺省的段寄存器为SS(即:堆栈段 BP是和堆栈指针SP联合使用的,作为SP校准使用的,只有在寻找堆栈里的数据)。 比如下面指令时正确的: 在[…]中,这4个寄存器可以单个出现,或只能以4种组合出现:BX和SI,BX和DI,BP和SI,BP和DI,比如下面的指令时正确的: 只要在[…]中使用寄存器BP,而指令中没有显性地给出段地址,段地址就默认在SS中,比如:
MOV AX , [BP] ;
*注: 此转载为个人笔记之用,如有不妥,还望指正