美文网首页IT狗工作室C语言C语言&嵌入式
x86汇编基础-Move指令和基本寻址

x86汇编基础-Move指令和基本寻址

作者: 铁甲万能狗 | 来源:发表于2019-10-18 23:31 被阅读0次

本文的立意仅仅是讨论基本的x86汇编语法,。所以我要重申这里的汇编教程并不是深入研究汇编,本人也没有那么大的能耐。学习基础的汇编主要达到以下的程度即可。

  • 读懂常用的运算符指令
  • 读懂存储和加载指令
  • 了解x86和x86_64常用的寄存器的用途。
  • 了解基本的寻址模型。

了解基本的汇编以后,有什么用?

  • 加深你对C/C++的编译器行为和大部分内部操作大有益处
  • 让你了解到用C/C++实现的高层算法在汇编层面实现细节。
  • 让你更深入地了解函数栈调用的细节,能够写出高效的代码。

其实我这里可以提一个问题?你知道 以下简单的语句它们在计算机底层做了写什么操作吗?
int *a=123; 或
double b=456;
double *pp=b;

如果你心中没有明确的答案,请不要蛮目自信地欺骗自己C/C++的功底是如何如何地扎实.....,我自己都没自信心敢这么说?如果你打算专职用C/C++写算法实现的,那么基本的汇编功底是必须的。

之前我也写过一篇关于x64的汇编教程提交到寄存器和系统调用的基本关系《汇编语言基础:寄存器和系统调用》


上面的图例是一个比较完整的示意图,通常在IA32或x86_64中主要集中讨论CPU中的寄存器与主内存的数据交换,而其他的外部寄存器不在本文的讨论范围之内。

加载与存储

在汇编中mov指令主要用于在主内存(RAM)和寄存器之间传输数据,按照传递的方向可以分为两类

  • 加载(Load)指令:从主内存(RAM)寄存器传输数据,以一个给定的内存地址作为参数,他从内存中获取该地址位置存储的数据,并将该数据放入寄存器
  • 存储(Store)指令:即从寄存器中缓存的内存地址中所指向的目标位置,并将另外一个寄存器中缓存的数据保存到该目标位置,我们可以把内存看作已经编了号的数组,而通过索引就是内存地址,通过指定的内存地址可以在特定位置中的修改内存中的数据。

IA32中的寄存器

在IA32架构中有八个寄存器,其中有6个是通用的寄存器,另外两个是esp和ebp有特殊的用途,如你对栈有所了解的话,就知道esp是始终指向栈顶的,ebp始终指向栈底。对于EAX,EBX,ECX和EDX寄存器,也会通常使用小字节的数据类型。 例如,EAX的最低有效2字节可被视为称为AX的16位寄存器。 AX的最低有效字节可以用作单个8位寄存器,称为AL,而AX的最高有效字节可以用作单个8位寄存器,称为AH。 这些名称指的是相同的物理寄存器。 当将两个字节的数量放入DX中时,更新将影响DH,DL和EDX的值。 这些子寄存器主要是较旧的16位版本指令集的保留。 但是,在处理小于32位(例如1字节ASCII字符)的数据时,它们有时很方便。


图片来源于网络

mov指令的长度分类

根据操作数的字长可以分为三个版本的mov指令

  • movl Source Dest : L表示可以移动4个字节
  • movw Source Dest: W表示可以移动2个字节
  • movb Source Dest: B表示可以移动1个字节

mov指令的操作数

并且在移动指令中会用到两个操作数,Source表示移动的数据源,Dest表示移动的数据最后到达的位置。
通常在x86用的比较频繁的mov指令版本是32位的movl,这里就以 movl Source Dest为例子

mov指令的操作数通常分为三类

  • 立即数(Immediate) 可以将其视为常数,和C语言的常量类似,但是以“$”为前缀,例如0x400,-500
  • 寄存器(Register)可以是以上8个整数寄存器中的其中一个,例如:“%eax”,“%edx”,当我们执行类似“movl %eax %edx”这种情况下,eax寄存器就成为源参数,而edx寄存器就成为目标参数,其含义是获取eax中的内容并存储在edx中。
  • 内存(Memory):而内存作为操作数通常是由寄存器缓存给定的内存地址来间接去操作的,该地址占用4个字节,例如(%eax),当寄存器在一个括号中,我们就说eax持有一个指向RAM中的某个位置的地址,你可以类比为类似C/C++中的指针变量,的那么 movl (%eax) %ebx 表示的是什么意思呢?你可以考虑一下表示什么意思?

mov的操作数组合

movl指令通过不同类型的操作数组合,能够表达出不同类型的指令类型的。


mov的参数组合
  • 例如源参数是立即数,而目标参数是的寄存器,即“movl $123,%eax ”表示将常量保存在寄存器eax中,等价于C/C++声明并初始化一个变量例如
     int a=123;
    
    其实在C编译器对每个声明的基本数据类型的变量会映射到一个寄存器中,例如一个int类型4字节,会选择一个32位的寄存器类装载int整数等待CPU中的运算单元(AU)处理。
  • 源参数是立即数,而目标参数是一个主内存中的地址,即“movl $123,%(eax) ”表示将常量保存到eax寄存器中的存储的内存位置所指向的内存位置,同理等价的C/C++语句如下:
    int *a=123;
    
  • 源参数是寄存器,而目标参数也是寄存器,例如“movl %edx,%eax”其实就是在寄存器之间拷贝数据。
  • 源参数是寄存器,而目标参数是内存。其实就是一种存储类型,例如“movl %eax,(%edx)”,表示当前寄存器eax中的数据写回主内存中的某个位置,而这个位置是由寄存器edx保存的地址所指向的。
  • 源参数是内存,而目标参数是寄存器,例如“movl (%edx),%eax”这是从内存中加载数据到eax寄存器当中。因此表示加载指令的其中一种。

可能你会想到最后一种,有从“内存”到“内存”传递的指令类型吗?单一的一条指令是不可能的。只能通过两步实现

  • 首先“内存”到“寄存器”例如:“movl (%edx),%eax
  • 然后“寄存器”到“内存” 例如:“movl %eax,(%ecx)

基本的内存寻址模型

间接访问
就是“(R)”这种格式,R表示一个寄存器名称。寄存器中保存着一个内存地址,我们用mov指令操作主内存时,只能通过使用该寄存器中的内容去实现对该地址指向的RAM中位置进行读/写操作。对于操作系统来说,内存其实就是一个连续的字节数组,每个字节都有对应的编号,而这个编号就是内存地址,也可以理解为该字节数组的索引。

我们用“RAM”表示主内存,那么 (R) 其实等价于 RAM[Reg[R]],

那么“movl (%edx),%eax”类似这样的指令的含义到这里应该不用多说了吧!

移位寻址
英文名称叫“Displacement”,这个其实就是在间接寻址表达式的基础是加上一个有符号的整数N。在汇编中抽象的移位寻址表达式“N(R)

我们用“RAM”表示主内存,那么 N(R) 其实等价于 RAM[Reg[R]+N],

那么具体的例子就是

  • 例如 “-4(%ebp)”:表示ebp寄存器中缓存的内存地址向低地址方向移动了4个字节
  • 例如“8(%ebp)”:表示ebp寄存器中缓存的内存地址向高地址方向移动8个字节。
  • 那么像这种“movl 4(%esp),%ecx”其实就是寄存器esp的指针向高地址方向偏移4个字节后的个新的地址,从该新地址指向的内存位置获取数据并保存到寄存器ecx。

相关文章

  • x86汇编基础-Move指令和基本寻址

    本文的立意仅仅是讨论基本的x86汇编语法,。所以我要重申这里的汇编教程并不是深入研究汇编,本人也没有那么大的能耐。...

  • ARM汇编之内存寻址模式

    对加载和存储的汇编指令目前有三种寻址模式:偏移寻址(Offset addressing),前变址寻址(Pre-in...

  • 汇编程序基础

    汇编程序基础 一、汇编程序基本结构 二、汇编指令 1.汇编指令基本结构 三、伪指令 1.段定义 2.数据定义 数据...

  • 汇编指令

    X86和X87汇编指令大全(有注释) ---------- 一、数据传输指令 ------------------...

  • 8086 指令系统寻址方式

    整理汇编语言学习笔记,回顾一下8086 指令系统的寻址方式。 寻址与指令 寻址方式(Addressing Mode...

  • 学习汇编--写一个完整的汇编(一)

    汇编指令 汇编有两类指令组成汇编指令如move,add,sub等,有对应的机器指令,可以被编译为机器指令最终被CP...

  • 关于Java的跨平台性,字节码和汇编码

    我们知道,C和C++是将源代码编译成平台相关的汇编指令(比如x86架构汇编指令,arm架构汇编指令),这就导致了已...

  • ARM 汇编指令学习:[1]ARM指令寻址方式

    ARM 汇编指令学习:[1]ARM指令寻址方式 一、数据处理指令的操作数的寻址方式 通常具有下面3种格式: 1、 ...

  • <<汇编语言>>第1章笔记

    第一章 基础知识 汇编语言基本概念 汇编指令是机器指令便于记忆的书写格式,通过编译器把汇编指令对应到机器指令,汇编...

  • x86汇编基础-内存寻址模型

    到目前位置,我们了解的到内存寻址最简单的方法就是移位寻址,但对于分析C/C++一些复杂的代码片段更底层操作原理,仅...

网友评论

    本文标题:x86汇编基础-Move指令和基本寻址

    本文链接:https://www.haomeiwen.com/subject/smrdmctx.html