汇编语⾔⼊门汇编指令及寄存器详解教程
⽬录
前⾔
什么是汇编语⾔
汇编语⾔产⽣的原因
汇编与⼆进制的关系
寄存器
寄存器作⽤
存取速度⽐较
寄存器分类
常⽤寄存器⽤途
寄存器EAX、AX、AH、AL的关系
汇编语⾔指令
数据传送指令
算术运算指令
逻辑运算指令
循环控制指令
转移指令
linux 和 windows 下汇编的区别
总结
前⾔
我们⼤都是被⾼级语⾔惯坏了的⼀代,源源不断的新特性正在逐步添加到各类⾼级语⾔之中,汇编作
为最接近机器指令的低级语⾔,已经很少被直接拿来写程序了,不过我还真的遇到了⼀个,那是之前的⼀个同事,因为在写代码时遇到了成员函数权限及可见性的问题,导致他⽆法正确调⽤想执⾏的函数,结果他就开始在C++代码⾥嵌⼊汇编了,绕过了种种限制终于如愿以偿,但是读代码的我们傻眼了…
因为项⽬是跨平台的,代码推送的 Linux 上编译的时候他才发现,汇编代码的语法在 Linux 和 Windows 上居然是不⼀样的,结果他⼜⽤⼀个判断平台的宏定义“完美”的解决了,最终这些代码肯定是重写了啊,因为可读性太差了,最近在学习左值、右值、左引⽤和右引⽤的时候,总是有⼈⽤程序编译⽣成的中间汇编代码来解释问题,看得我迷迷糊糊,所以决定熟悉⼀下简单的汇编指令,边学习边记录,⽅便今后忘记了可以直接拿来复习。
什么是汇编语⾔
汇编语⾔是最接近机器语⾔的编程语⾔,引⽤百科中的⼀段话解释为:
汇编语⾔(assembly language)是⼀种⽤于电⼦计算机、微处理器、微控制器或其他可编程器件的低级语⾔,亦称为符号语⾔。在汇编语⾔中,⽤助记符代替机器指令的操作码,⽤地址符号或标号代替指令或操作数的地址。汇编语⾔⼜被称为第⼆代计算机语⾔。
汇编语⾔产⽣的原因
对于绝⼤多数⼈来说,⼆进制程序是不可读的,当然有能⼈可以读,⽐如第⼀代程序员,但这类⼈快灭绝了,直接看⼆进制不容易看出来究竟做了什么事情,⽐如最简单的加法指令⼆进制表⽰为00000011,如果它混在⼀⼤串01字符串中就很难把它出来,所以汇编语⾔主要就是为了解决⼆进制编码的可读性问题。
汇编与⼆进制的关系
换句话来说,汇编语⾔就是把给机器看的⼆进制编码翻译成⼈话,汇编指令是机器指令的助记符,与机器指令是⼀⼀对应的关系,是⼀种便于阅读和记忆的书写格式。有效地解决了机器指令编写程序难度⼤的问题,并且使⽤编译器,可以很⽅便的把汇编程序转译成机器指令程序,⽐如之前提到的00000011加法指令,对应的汇编指令是ADD,在调⽤汇编器时就会把ADD翻译成00000011。
寄存器
说到汇编指令不得不提到寄存器,寄存器本⾝是⽤来存数据的,因为CPU本⾝只负责逻辑运算,数据需要单独储存在其他的地⽅,但是对于不熟悉寄存器的⼈来说会有疑惑,数据不是存在硬盘上吗?或者说数据不是存在内存中吗?这些想法都没错,那么寄存器是⽤来做什么的呢?
寄存器作⽤
其实硬盘、内存都是⽤来存储数据的,但是CPU的运算速度远⾼于内存的读写速度,更不⽤说从硬盘上取数据了,所以为了避免被拖慢速度影响效率,CPU都⾃带⼀级缓存和⼆级缓存,⼀些CPU甚⾄增加了三级缓存,从这些缓存中读写数据要⽐内存快很多,但是还是⽆法使⽤飞速运转的CPU,所以才会有寄存器的存在。
寄存器不是后来增加的,在最初的计算中就已经设计出来,相⽐⽽⾔,多级缓存出现的更晚⼀些,通常那些最频繁读写的数据都会被放在寄存器⾥⾯,CPU优先读写寄存器,再通过寄存器、缓存跟内存来交换数据,达到缓冲的⽬的,因为可以通过名称访问寄存器,这样访问速度是最快的,因此也被称为零级缓存。
存取速度⽐较
通过上⾯的叙述我们可以知道存取速度从⾼到低分别是: 寄存器 > 1级缓存 > 2级缓存 > 3级缓存 > 内存 > 硬盘,关于它们的存取速度,举个例⼦很容易就能明⽩了,⽐如我们做菜(CPU⼯作)时,取⼿中(寄存器)正拿着的⾁和蔬菜肯定是最快的,如果没有就需要把案板上(1级缓存)处理好的菜拿过来,如果案板上没有就在更远⼀点的洗菜池(2级缓存)中⼀,还没到的话就要到冰箱(3级缓存)中看⼀看了,这时发现家⾥真没有,那去楼下的菜店(内存)去买点吧,转了⼀圈发现没有想要的,最后还是开车去农贸市场(硬盘)买吧。
通过上⾯这个例⼦应该能明⽩它们的速度关系了,既然缓存这么快,为什么不⽤缓存代替内存,或者将2、3级缓存都换成1级缓存呢?这⾥边有⼀个成本问题,速度越快对应着价格越⾼,如果你买过机械硬盘和固态硬盘应该很容易就理解了。
寄存器分类
常⽤的x86 CPU寄存器有8个:EAX、EBX、ECX、EDX、EDI、ESI、EBP、ESP,据说现在寄存器总数已经超过100个了,等我到相关资料再来补充,上⾯这⼏个寄存器是最常⽤的,这些名字也常常出现在汇编的代码中。
我们常说的32位、64位CPU是指数据总线的宽度或根数,⽽寄存器是暂存数据和中间结果的单元,因此寄存器的位数也就是处理数据的长度与数据总线的根数是相同的,所以32位CPU对应的寄存器也应该是32位的。
常⽤寄存器⽤途
上⾯提到⼤8个寄存器都有其特定的⽤途,我们以32位CPU为例简单说明下这些寄存器的作⽤,整理如下表:
寄存器含义⽤途
包含寄存
器
EAX累加(Accumulator)寄
存器常⽤于乘、除法和函数返回值
AX(AH、
AL)
EBX基址(Base)寄存器常做内存数据的指针, 或者说常以它为基址来访问内存.BX(BH、
BL)
ECX计数器(Counter)寄存
器常做字符串和循环操作中的计数器
CX(CH、
CL)
EDX数据(Data)寄存器常⽤于乘、除法和 I/O 指针DX(DH、
DL)
ESI来源索引(Source
Index)寄存器常做内存数据指针和源字符串指针SI
EDI⽬的索引(Destination
Index)寄存器常做内存数据指针和⽬的字符串指针DI
ESP堆栈指针(Stack Point)
寄存器
只做堆栈的栈顶指针; 不能⽤于算术运算与数据传送SP
EBP基址指针(Base Point)
寄存器只做堆栈指针, 可以访问堆栈内任意地址, 经常⽤于中转 ESP 中的数据, 也常以它为基
址来访问堆栈; 不能⽤于算术运算与数据传送
BP
寄存器EAX、AX、AH、AL的关系
在上⾯的图标中每个常⽤寄存器后⾯还有其他的名字,它们是同⼀个寄存器不同⽤法下的不同名字,⽐如在32位CPU 上,EAX是32位的寄存器,⽽AX是EAX的低16位,AH是AX的⾼8位,⽽AL是AX的低8位,它们的对照关系如下:
00000000 00000000 00000000 00000000
|===============EAX===============|---4个字节
|======AX=======|---2个字节
|==AH===|-----------1个字节
|===AL==|---1个字节
汇编语⾔指令
终于说到汇编常⽤指令了,因为linux和windows下的汇编语法是有些不同的,所以下⾯我们先通过windows下的汇编指令来简单学习⼀下,后续再来⽐较两者的不同。
数据传送指令
指令名称⽰例备注
MOV传送指令MOV dest, src将数据从src移动到dest
PUSH进栈指令PUSH src把源操作数src压⼊堆栈
POP出栈指令POP desc从栈顶弹出字数据到dest
算术运算指令
指令名称⽰例备注
ADD加法指令ADD dest, src在dest基础上加src
SUB减法指令SUB dest, src在dest基础上减src
INC加1指令INC dest在dest基础上加1
DEC减1指令DEC dest在dest基础上减1
逻辑运算指令
指令名称⽰例备注
汇编语言要什么基础NOT取反运算指令NOT dest把操作数dest按位取反
AND与运算指令AND dest, src把dest和src进⾏与运算之后送回dest
OR或运算指令OR dest, src把dest和src进⾏或运算之后送回dest
XOR异或运算XOR dest, src把dest和src进⾏异或运算之后送回dest
循环控制指令
指令名称⽰例备注
LOOP计数循环指令LOOP label使ECX的值减1,当ECX的值不为0的时候跳转⾄label,否则执⾏LOOP之后的语句
转移指令
指令名称⽰例备注
JMP⽆条件转移指令JMP lable⽆条件地转移到标号为label的位置
CALL过程调⽤指令CALL labal直接调⽤label
JE条件转移指令JE lable zf =1 时跳转到标号为label的位置
JNE条件转移指令JNE lable zf=0 时跳转到标号为label的位置
linux 和 windows 下汇编的区别
前⾯说到linux和windows下的汇编语法是不同的,其实两种语法的不同和系统不同没有绝对的关系,⼀般在linux上会使⽤gcc/g++编译器,⽽在windows上会使⽤微软的cl也就是MSBUILD,所以产⽣不同的代码是因为编译器不同,gcc下采⽤的是
AT&T的汇编语法格式,MSBUILD采⽤的是Intel汇编语法格式。
差异Intel AT&T
引⽤寄存器名字eax%eax
赋值操作数顺序mov dest, src movl src, dest
寄存器、⽴即数
指令前缀
mov ebx, 0xd00d movl $0xd00d, %ebx
寄存器间接寻址[eax](%eax)
数据类型⼤⼩操作码后加后缀字母,“l” 32位,“w” 16位,“b” 8位
(mov dx, word ptr [eax])
操作数前⾯加dword ptr, word ptr,byte ptr的格
式(movb %bl %al)
总结
汇编指令是机器指令的助记符,与机器指令是⼀⼀对应的
AT&T的汇编语法格式和Intel汇编语法格式的是不同的
常⽤寄存器:EAX、EBX、ECX、EDX、EDI、ESI、EBP、ESP
存取速度从⾼到低分别是: 寄存器 > 1级缓存 > 2级缓存 > 3级缓存 > 内存 > 硬盘
的汇编指令:mov、je、jmp、call、add、sub、inc、dec、and、or
如今的每分每秒都是⼈⽣,不要总想着将⾃然发⽣的事情拖到预定的时刻才进⾏~
以上就是汇编语⾔⼊门汇编指令及寄存器详解教程的详细内容,更多关于汇编语⾔指令及寄存器的资料请关注其它相关⽂章!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论