C语言的本质(29)——C语言与汇编之寄存器和寻址方式

x86的通用寄存器有eax、ebx、ecx、edx、edi、esi。这些寄存器在大多数指令中是可以任意选用的,比如movl指令可以把一个立即数传送到eax中,也可传送到ebx中。但也有一些指令规定只能用其中某些寄存器做某种用途,例如除法指令idivl要求被除数在eax寄存器中,edx寄存器必须是0,而除数可以在任意寄存器中,计算结果的商数保存在eax寄存器中,而原来的被除数被覆盖掉,余数保存在edx寄存器中。也就是说,通用寄存器对于某些指令而言不是通用的。

x86的特殊寄存器有ebp、esp、eip、eflags。eip是程序计数器,eflags保存着计算过程中产生的标志位,包括进位、溢出、零、负数四个标志位,在x86的文档中这几个标志位分别称为CF、OF、ZF、SF。ebp和esp用于维护函数调用的栈帧。

下面我们通过一个求一组数的最大值的汇编程序来体会:

#max.asm
.section .data
data_items: #数据项,即数组元素
.long3,67,34,222,45,75,54,34,44,33,22,11,66,0 .section .text
.globl _start
_start:
movl$0, %edi # 把当前位置0存入%edi寄存器
movldata_items(,%edi,4), %eax #从数据的第一个整数开始处理
movl%eax, %ebx # 因为是数据的第一个数字,所以当前%eax的值是最大的 start_loop: # 循环开始
cmpl$0, %eax # 检查是否已经把所有的数字遍历了
jeloop_exit
incl%edi # 处理下一个数字
movldata_items(,%edi,4), %eax
cmpl%ebx, %eax # 比较数值
jlestart_loop # 如果新的数字不是最大的值,就跳转回循环的开始
movl%eax, %ebx #如果是最大值,那么就把这个数字取代原来的最大值 move the value as the largest
jmpstart_loop # 继续循环 loop_exit:
movl$1, %eax
int$0x80

汇编、链接、执行:

aaarticlea/png;base64,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" alt="" />

可以看到最大数为222。

这个程序在一组数中找到一个最大的数,并把它作为程序的退出状态。这组数在.data段给出:

data_items:
.long3,67,34,222,45,75,54,34,44,33,22,11,66,0

.long指示声明一组数,每个数占32位,相当于C语言中的数组。这个数组开头有一个标号data_items,汇编器会把数组的首地址作为data_items符号所代表的地址,data_items类似于C语言中的数组名。data_items这个标号没有用.globl声明,因为它只在这个汇编程序内部使用,链接器不需要知道这个名字的存在。除了.long之外,常用的数据声明还有:

.byte,也是声明一组数,每个数占8位

.ascii,例如.ascii "Helloworld",声明了11个数,取值为相应字符的ASCII码。注意,和C语言不同,这样声明的字符串末尾是没有'\0'字符的,如果需要以'\0'结尾可以声明为.ascii "Hello world\0"。

data_items数组的最后一个数是0,我们在一个循环中依次比较每个数,碰到0的时候让循环终止。在这个循环中:

edi寄存器保存数组中的当前位置,每次比较完一个数就把edi的值加1,指向数组中的下一个数。

ebx寄存器保存到目前为止找到的最大值,如果发现有更大的数就更新ebx的值。

eax寄存器保存当前要比较的数,每次更新edi之后,就把下一个数读到eax中。

_start:
movl $0, %edi

初始化edi,指向数组的第0个元素。

movl data_items(,%edi,4), %eax

这条指令把数组的第0个元素传送到eax寄存器中。data_items是数组的首地址,edi的值是数组的下标,4表示数组的每个元素占4字节,那么数组中第edi个元素的地址应该是data_items + edi * 4,从这个地址读数据,写成指令就是上面那样,这种地址的表示方式在后面还会详细解释。

 movl%eax, %ebx

ebx的初始值也是数组的第0个元素。下面我们进入一个循环,在循环的开头用标号start_loop表示,循环的末尾之后用标号loop_exit表示。

start_loop:
cmpl $0, %eax
je loop_exit

比较eax的值是不是0,如果是0就说明到达数组末尾了,就要跳出循环。cmpl指令将两个操作数相减,但计算结果并不保存,只是根据计算结果改变eflags寄存器中的标志位。如果两个操作数相等,则计算结果为0,eflags中的ZF位置1。je是一个条件跳转指令,它检查eflags中的ZF位,ZF位为1则发生跳转,ZF位为0则不跳转,继续执行下一条指令。可见条件跳转指令和比较指令是配合使用的,前者改变标志位,后者根据标志位做判断,如果参与比较的两数相等则跳转,je的e就表示equal。

 incl%edi
movldata_items(,%edi,4), %eax

将edi的值加1,把数组中的下一个数传送到eax寄存器中。

 cmpl%ebx, %eax
jlestart_loop

把当前数组元素eax和目前为止找到的最大值ebx做比较,如果前者小于等于后者,则最大值没有变,跳转到循环开头比较下一个数,否则继续执行下一条指令。jle也是一个条件跳转指令,le表示less than or equal。

 movl%eax, %ebx
jmpstart_loop

更新了最大值ebx然后跳转到循环开头比较下一个数。jmp是一个无条件跳转指令,什么条件也不判断,直接跳转。loop_exit标号后面的指令用_exit系统调用退出程序。

通过这个例子我们了解到,访问内存时在指令中可以用多种方式表示内存地址,比如可以用数组基地址、元素长度和下标三个量来表示,增加了寻址的灵活性。下面介绍x86常用的几种寻址方式(Addressing Mode)。内存寻址在指令中可以表示成如下的通用格式:

ADDRESS_OR_OFFSET(%BASE_OR_OFFSET,%INDEX,MULTIPLIER) 

它所表示的地址可以这样计算出来:

FINAL ADDRESS = ADDRESS_OR_OFFSET +BASE_OR_OFFSET + MULTIPLIER * INDEX

其中ADDRESS_OR_OFFSET和MULTIPLIER必须是常数,BASE_OR_OFFSET和INDEX必须是寄存器。在有些寻址方式中会省略这4项中的某些项,相当于这些项是0。

常见的寻址方式:

1、直接寻址(Direct Addressing Mode)。只使用ADDRESS_OR_OFFSET寻址,例如movl ADDRESS, %eax把ADDRESS地址处的32位数传送到eax寄存器。

2、变址寻址(Indexed Addressing Mode) 。上一节的movldata_items(,%edi,4), %eax就属于这种寻址方式,用于访问数组元素比较方便。

3、间接寻址(Indirect Addressing Mode)。只使用BASE_OR_OFFSET寻址,例如movl(%eax), %ebx,把eax寄存器的值看作地址,把这个地址处的32位数传送到ebx寄存器。注意和movl %eax, %ebx区分开。

4、基址寻址(Base Pointer Addressing Mode)。只使用ADDRESS_OR_OFFSET和BASE_OR_OFFSET寻址,例如movl4(%eax), %ebx,用于访问结构体成员比较方便,例如一个结构体的基地址保存在eax寄存器中,其中一个成员在结构体内的偏移量是4字节,要把这个成员读上来就可以用这条指令。

5、立即数寻址(Immediate Mode)。就是指令中有一个操作数是立即数,例如movl $12, %eax中的$12,这其实跟寻址没什么关系,但也算作一种寻址方式。

6、寄存器寻址(Register Addressing Mode)。就是指令中有一个操作数是寄存器,例如movl$12, %eax中的%eax,这跟内存寻址没什么关系,但也算作一种寻址方式。在汇编程序中寄存器用助记符来表示,在机器指令中则要用几个Bit表示寄存器的编号,这几个Bit也可以看作寄存器的地址,但是和内存地址不在一个地址空间。

上一篇:Maven依赖中的scope详解,在eclipse里面用maven install可以编程成功,到服务器上用命令执行报VM crash错误


下一篇:【死磕 Spring】----- IOC 之 属性填充