(1)汇编语言之寄存器,操作数寻址方式

写在前面:汇编语言格式有AT&T和Intel格式两种,GCC编译器采用AT&T格式,本系列文章中的所有汇编指令都采用此格式。数据格式采用IA32体系结构的Intel格式,用“字”(word)表示16位数据,用“双字”(double word)表示32位数据,用“四字”(quad word)表示64位数据

一、 什么是汇编语言

 我们熟悉的C语言,Java,Python等语言都是高级语言,高级语言不能被处理器识别,程序运行时,需要将代码转成处理器能识别的机器码。机器码是一串十六进制的数字,如 55 5D 89 E5。由于人很难理解机器码表达的意思,因此需要用一些符号帮助理解指令。这种用符号代替机器指令操作码的低级语言称为汇编语言。机器码与汇编指令的关系如下图所示。
  汇编语言由一条一条指令构成,由上图右半部分所示。指令有两部分组成,第一部分是操作码,用便于记忆的助记符表示,另一部分是操作数。一条指令可以有零个,一个或两个操作数。如“push %ebp” 只有一个操作数,这个指令的意思是将寄存器%ebp的值压入栈。如“mov %esp %ebp”有两个操作数,分别称为源操作数和目的操作数,这个指令的意思是将寄存器%esp的值传送给寄存器%ebp。

二、寄存器

 程序编译后的指令代码存放在存储器中。CPU如何执行程序?简单的说,就是取指令,执行指令。CPU从存储器中取出一条指令,分析后执行相应的操作。如:x+y。GCC编译后产生三条指令,第一条指令告诉CPU从存储器中取出x的值,放在CPU的寄存器中,第二条指令告诉CPU从存储器中取出y的值,放在CPU的寄存器中,第三条指令告诉CPU将两个寄存器的值相加。
 寄存器用来存储整数数据以及指针,一个IA32指令集架构的处理器包含一组8个32位的寄存器。

32 16 高8位 低8位
%eax %ax %ah %al
%ecx %cx %ch %cl
%edx %dx %dh %dl
%ebx %bx %bh %bl
%esi %si
%edi %di
%esp %sp
%ebp %bp

 32位处理器需要向后兼容16位处理器。表中%eax对应32位寄存器,%ax对应16位寄存器,%ax寄存器由%ah与%al组成,%ah与%al分别表示寄存器的高八位与低八位。
  表中前6个寄存器是通用寄存器,可以存放数据和指针。%esp是栈指针寄存器,%ebp是帧指针寄存器。%eax %ecx %edx是调用者保存寄存器,指的是当一个函数P调用另一个函数Q时,由于寄存器数量有限,函数Q可以写这些寄存器。%ebx %esi %edi是被调用者保存寄存器,指的是当一个函数P调用另一个函数Q时,需要先把这些寄存器的值保存在存储器中,之后,函数Q才可以写这些寄存器。这个现象可以称为保存现场。当函数调用结束后,保存在存储器中的值会被恢复到寄存器中,称为恢复现场

三、操作数寻址方式

 操作数分为三种:立即数(immediate),寄存器,存储器的引用。翻译一下,就是常数,寄存器中的值(用 R [ E a ] R[E_a] R[Ea]表示),存储器中的值(用 M [ a d d r ] M[addr] M[addr]表示)。而寻址的意思就是如何得到操作数表达的值。
在这里插入图片描述 举一个例子就可以明白上图中表达的意思。
 假设存储器地址中的值如下所示:

地址
0X100 0XFF
0X104 0XAB
0X108 0X13
0X10C 0X11

寄存器中的值如下所示:

寄存器
%eax 0X100
%ecx 0X1
%edx 0X3

那操作数与值的对应关系如下表所示:

操作数
%eax 0X100
0X104 0XAB
$0X108 0X108
(%eax) 0XFF
4(%eax) 0XAB
9(%eax,%edx) 0X11
(%eax,%edx,4) 0X11
0XFC(,%ecx,4) 0XFF

以9(%eax,%edx)为例,9(%eax,%edx)=M[9+%eax+%edx] = M[0X9+0X100+0X3]=M[0X10C],表示存储器0X10C地址的值,在第一张表上可以查到,地址0x10C上的值为0x11。

猜你喜欢

转载自blog.csdn.net/zhong_ethan/article/details/102487291