阅读本文之前,如果对寻址方式不清楚,可参阅上一篇文章(1)汇编语言之寄存器,操作数寻址方式。
一、数据格式
C语言有不同的数据格式,如char,short,int,long等。汇编语言针对不同数据有不同的操作码形式,如movb(传送字节),movw(传送字),movl(传送双字)。本篇及后面几篇文章皆采用32位的Intel格式,如下图所示:
Intel数据类型 | 汇编代码后缀 | 大小(字节) |
---|---|---|
字节 | b | 1 |
字 | w | 2 |
双字 | l | 4 |
单精度 | s | 4 |
双精度 | l | 8 |
二、数据传送指令
数据传送指令的目的是将源操作数的值复制到目的操作数中。源操作数是一个立即数,在寄存器或者存储器中。目的操作数是一个地址,可以是寄存器或者存储器地址。IA32指令集的数据传送指令如下图所示。
上表中符号扩展是指目的位置的所有高位用源值的最高位数值进行填充。零扩展是指目的位置的所有高位用零填充。用下面几个例子加强理解。
序号 | 指令 | 结果 |
---|---|---|
1 | movl $0x4050,%eax | Imm->Reg, 4bytes |
2 | movw %bp,%sp | Reg->Reg,2bytes |
3 | movb (%edi,%ecx),%ah | Mem->Reg,1byte |
4 | movb $-17,(%esp) | Imm->Mem,1byte |
5 | movl %eax,-12(%ebp) | Reg->Mem,4bytes |
6 | 以下假设%dh=CD,%eax=98765432 | |
7 | movb %dh,%al | %eax=987654CD |
8 | movsbl %dh,%eax | %eax=FFFFFFCD |
9 | movzbl %dh,%eax | %eax=0000000CD |
三、处理器工作流程
处理器运行一条指令流程可简单分为:取指令,译码,执行,访存,写回,更新PC(程序计数器,即当前指令地址)。
取指令:处理器从PC指定的地址取出一条指令。一条指令由指令代码以及寄存器操作数rA或rB构成,有的指令还包含一个常数valC。下一条指令的地址valP等于PC的值加上取出指令的长度。
译码:将rA或rB指定的寄存器值赋值给valA或valB。
执行:算术/逻辑单元(ALU)根据指令代码指明的操作,计算相关数据,把结果放在valC中。
访存:处理器将结果写入存储器,或从存储器中读出数据,赋值给valM。
写回:将结果写回到寄存器中。
更新PC:将PC设置成下一条指令的地址。
下面将mov指令执行过程按上面步骤进行拆解,假设指令代码大小为1个字节,寄存器rA:rB占用一个字节,常数占用四个字节:
阶段 | movl rA, rB | movl Imm, rB |
---|---|---|
取指令 | icode = M[PC] rA:rB=M[PC+1] valP=PC+2 | icode = M[PC] rA:rB=M[PC+1] valC=M[PC+2] valP=PC+6 |
译码 | valA=R[rA] | – |
执行 | valE=0+valA | valE=0+valC |
访存 | – | – |
写回 | R[rB]=valE | R[rB]=valE |
更新PC | PC=valP | PC=valP |