程序的机器级表示

程序编码

机器级代码

计算机系统利用抽象模型产生细节

1.指令集体系结构或指令级架构(它是软硬件之间的“合同”):定义了处理器状态、指令的格式、指令对状态的影响

2.使用的内存地址是虚拟地址:机器代码将内存看成一个按字节寻址的数组

程序处理器:给出将要执行的下一条指令在内存中的地址

整数寄存器文件包含16个命名的位置,分别储存64位的值。(可以储存地址或者整数数据)

条件码寄存器保存着最近算数或逻辑的指令的状态信息。(可用来实现if while函数)

一组向量寄存器可以储存一个或者多个整数或者浮点数值

操作系统负责管理虚拟地址空间,将虚拟地址翻译成实际处理器中的物理地址

代码具体

先创建一个c代码

1
touch +“文件名”.c

vim “文件名”.c

1
2
3
gcc -Og -S ""//预处理代码,可生成.s后缀的文件
gcc -Og -c ""//编译并汇编代码,可生成.o后缀的文件
objdump -d ""//objdump是一种反汇编程序,反汇编该代码

链接器的任务之一就是为函数找到匹配的可执行代码的位置

反汇编后

所有以”.”开头的为伪指令,可以忽略

数据格式

数据传送指令

movb(字节)

movw(字)

movl(双字)

movq(四字)

movabsq(传输绝对的四字)

49:20

访问信息

一个CPU包含了一组16个储存64位值的通用寄存器

以%r 开头的

在指令以寄存器作为目标时,对于生成小于8字节的指令:

生成1字节和2字节数字的指令会保持剩下的字节的不变

生成4字节数字的指令会把高位4个字节设置位零

操作数指示符

1.立即数

用来表示常数值

书写方式为:“$”后面跟着一个标准C表示的整数

2.寄存器

表示某个寄存器的内容

16寄存器的低位1字节,2字节,4字节,8字节中的一个作为一个操作数,其分别对应8位,16位,32位,64位

3.内存引用

根据计算出来的地址(有效地址)访问一些位置

当Imm(,ri,s),寻址的位置为:Imm+ri*s

就是括号里三个寻址对象是,第二个和第三个相乘

:::::就是汇编语言中寻址的方式:::::

数据传输指令

X86-64 系统的限制:传输指令的两个操作数不能都指向内存位置

在将较小的源值复制到较大的目的时:

movz类

把传输到目的的中剩余的字节填充为0

movzbw 后两个字符分别代表第一个字符指定的源大小,和目的位置的源大小

movs类

就是进行符号填充,把源操作的最高位进行复制

movl

把4字节的源值拓展到8字节

%rax(64)=%eax(32)+%ax(16)+%ah(8)+%al(8)

压入和弹出数据

栈向下增长,栈顶的地址是栈中元素地址中最低的。栈指针 rsp 保存栈顶元素的地址

栈指令:

1
2
3
4
pushq s //R[%rsp]=R[%rsp]-8
//M[R[%rsp]]=s
popq D //D=M[R[%rsp]]
//R[%rsp]=R[%rsp]+8

使用 mov 指令和标准的内存寻址方法可以访问栈内的任意位置,而非仅限于栈顶

算数和逻辑操作

整数算数操作

加载有效地址

指令leaq:加载有效地址,就是mov指令的变形

1
2
3
4
5
long scale(long x,long y,long z)
{
long t=x+4*y+12*z;
return t;
}
1
2
3
4
scale:
leaq (%rdi,%rsi,4),%rax x+4*y
leaq (%rdx,%rdx,2),%rdx z=z+2*z
leaq (%rax,%rdx,4),%rax x+4*y+4*(3*z)

其他的指令如上图

特殊的算数运算

特殊的算数运算

要求被乘数放在了%rax中

imulp:计算结果存放(%rdx高位 %rax低位)用于有符号数

mulp:用于无符号数

控制

条件码

单个位的条件码寄存器:(判断状态)

CF :进位标志(检测无符号溢出)

ZF :零标志

SF:符号标志

OF:溢出标志(正溢出,负溢出)

访问条件码

三种使用方法

1.根据条件码的某种组合,将第一个字节设置为0或者1

2.条件跳转到其他的程序部分

3.有条件的传送数据

SET指令

SET指令

跳跃指令

无条件跳转:jump

其他跳转指令

其他跳转指令

跳转指令在反汇编中的值为跳转到的那个指令的地址,也就是跳转指令后面的那个地址

C语言的if-else通用式转化在汇编中实现模板

1
2
3
4
if(test-expr)
then-statement
else
else-statement
1
2
3
4
5
6
7
8
t=test-expr;
if(!t)
goto false;
then-statement
goto done;
false:
else-statement;
done;

条件传送:

条件传送