题外话:其实以前读书的时候学校有开过汇编这门课程的,不过我压根就没去过那堂课。所以现在趁下班的时候自学汇编,弥补一下年少的无知,也算是一种安慰~
本文以及余下的所有文都是针对ATT汇编的,请一定要对号入座,现在写下的内容只能算作我个人的读书笔记,难免有出错之处,欢迎批评指正。
IA32整数寄存器
学习汇编,不得不了解寄存器,顾名思义,寄存器就是用来存放数据的容器,比如存储程序里某个int变量的值,或者是某个指针指向的值等等,那么现在先从整数寄存器入手。
在IA32中央处理单元(CPU)中,包含了8个32位整数寄存器(如下图)。从图中可以看到在每个32位寄存器的名字前面都会有一个%e,在这里可以把e理解成extended(扩展的),因为早期的8086寄存器是16位,所以加e之后就变成32位的了。
图1 IA32整数寄存器
虽然现在的寄存器是32位的了,但仍然不影响我们对16位寄存器的使用,图中的ax,cx,dx,bx,si,di,sp,bp均是16位寄存器,并且也可用通过ah访问ax的高8位,al访问ax的低8位(cx,dx,bx访问方法类似)。
一般而言,前面6个32位寄存器都是通用的,除开某些特定操作会用到特定的寄存器之外,你可以随意使用它们。除此之外,在过程(functions)处理中,针对前3个寄存器的处理会不同于后3个,但目前来说,你并不需要关心这些差异。
但值得注意的是:最后两个寄存器是不能随便乱动的,因为它们保存着指向程序栈重要位置的指针。
下面做一个简单的总结,让条理清晰一点:
1、IA32中总共有8个32位寄存器(请不要太过关注这些寄存器奇怪的名字),如果要访问寄存器中32位数据的值,你需要使用%e??这种形式,如果要访问某个寄存器低16位的值你需要使用%?x,%?i或者%?p 这种形式,如果你需要访问高8位需要使用 %?h这种形式,如果要访问低8位,则需要使用%?l这种形式。
2、前6个寄存器是通用的(在遵循一定的使用规则前提下,可以随意更改寄存器中的值),后两个寄存器是不能随意更改的。
3、IA32寄存器被划分为了8个32位寄存器,8个16位寄存器,以及8个8位寄存器。但实质上只有8个32位寄存器,无外乎玩了一场位游戏。
示例:假设32位寄存器%eax存储的值如下:
%eax : aa bb cc dd
那么下面寄存器对应的值为
%ax:cc dd
%ah:cc
%al::dd
因为第一个%ax代表取寄存器低16位的值,%ah代表取低16位中的高8位值,%al代表取低16位中的低8位值。