L05 Machine-Level Programming I:Basic

6次阅读
没有评论

L05 Machine-Level Programming I:Basic

将C转化为汇编

L05 Machine-Level Programming I:Basic

每行C语言代码都会被变成对应的汇编(-S 意为 stop; -Og 是优化)

汇编语言具有一些特性:

  • 整数的数据类型很多,有 1,2,4,8字节的,并且不区分有符号何无符号数。指针/地址 都是以数字形式存储的
  • 浮点数使用另外的寄存器,4,8,10字节
  • 本质上只是一串字节,不存在“数据结构”
  • 每条汇编语句的能力非常有限,本质上只是对寄存器/内存的操作
  • 对于x86 一条指令一个字节

L05 Machine-Level Programming I:Basic

‍

L05 Machine-Level Programming I:Basic

上面这张图说的是在x86-64中,各种寄存器。

其中 %r 是64位(8字节) %e是32位(4字节)

IA32到x86-64 的一大特点就是寄存器数量翻了一倍(左边那些%e打头的全是IA32时代的寄存器,而%r开头的属于x86-64)

L05 Machine-Level Programming I:Basic

旧机器可以访问,低16位位置,甚至2字节,1字节。

(现在 这些寄存器的名称与功能无关)

特殊的寄存器 %rsp 被称作栈指针(IA 32时代还有个basepointer 基指针,但是现在也不太用)

现在有八个寄存器用名字表示,有八个用数字表示。

对于寄存器,通常有以下操作:

  • move 移动 写为mov 可以做很多事情。通常是mov source dest

    1. Immediate:常整型数据
    2. Register:寄存器
    3. Memory:内存地址

    L05 Machine-Level Programming I:Basic

    为什么是五种呢?按理来说应该是九种。但是,常量作为dest是没有意义的,所以少了三种。除此之外 从内存到内存,为了方便硬件设计,通常是先把内存中的数据读取到寄存器,随后再把寄存器写回内存。而不是直接mov men men

    如果寄存器出现在()内,那么是把寄存器里面的数据当作内存地址来读取

    L05 Machine-Level Programming I:Basic

    %rdi 用来存储第一个参数 %rsi用来存储第二个参数,因此在上面的例子中, %rdi用来存储 *xp 的指针。

    L05 Machine-Level Programming I:Basic

    L05 Machine-Level Programming I:Basic

    如图所示的是,比例变址寻址,是一种常用的数组实现方式,根据数据类型大小来放缩实现寻址

    L05 Machine-Level Programming I:Basic

    通过上述表格 我们可以了解到一些运算规则

  • lea 是一种特殊的计算语句

    lea source dest

    L05 Machine-Level Programming I:Basic

    当 () 出现在 movq 后面时,括号的意思是:“拿着这个地址,去内存里取值”(必须是个合法地址)。
    当 () 出现在 leaq 后面时,括号的意思是:“请计算括号里面这个表达式的值,计算完给我,我不去内存”。
    

    所以 在这里 %rdi里面存放了 x的值,直接被计算成了3x 然后被放入%rax中,随后通过向左位移的方式直接乘4 变成了计算*12

  • L05 Machine-Level Programming I:Basic

    更多的两个参数的汇编运算

  • L05 Machine-Level Programming I:Basic

    单参数运算

正文完
 0
评论(没有评论)