程序的机器级表示 - 访问数据

用户头像
引花眠
关注
发布于: 2020 年 07 月 26 日

C语言与汇编语言的数据格式对比

因为是从16位体系扩展到32位又扩展到64位,所以Inter用word表示16位数据类型,以此类推32位是double word(long word),64位是quad word,所以在汇编语言中,q代表四字

以下是x86-64中数据格式

C声明 Intel数据类型 汇编代码后缀 大小(字节)

char 字节 b 1

short 字 w 2

int 双字 l 4

long 四字 q 8

char* 四字 q 8

float 单精度 s 4

double 双精度 l 8

访问信息

一个x86-64CPU中包含16个通用的64位寄存器,这些寄存器可以存储整数数据和指针。这些寄存器一般以%r开头,后面跟着其他的名字,这些名字一般标志着其用途,具体的用途会在其他文章中介绍。

操作数

operand(操作数)用来表示一个指令中要使用的源数据的值与放置结果的目的位置。在操作数大致分为三类:

  1. 立即数 在ATT格式的汇编代码中用$与一个标准的C整数组合表示,比如 $-1

  2. 寄存器的内容 可以是1字节,2字节,四字节或8字节,用ra表示

  3. 内存的引用 用Mb[Addr]表示,b表示字节数

为了访问这三类操作数,所以有三种寻址模式:

  1. 立即数 格式:$Imm 操作数值:Imm

  2. 寄存器 格式:ra 操作数值:R[ra]

  3. 内存 格式:Imm(rb ,ri,s ),其中Imm立即数偏移,rb基址寄存器,ri变址寄存器,s比例因子,在这些中s必须是`1、2、4或8,操作数值:M[Imm+rb +ri * s]

数据传送指令

最常做的操作就是将数据从一个位置复制到另一个位置,在汇编语言中,这样的数据传送指令有很多,比如mov等。

mov指令系列

mov系列指令是最简单的数据传送指令,它只是将数据不做任何改变的从源位置复制到目的位置。其格式类似为mov S,D,在mov后接一个字符代表操作的数据长度,比如movb传送一个字节,movl传送双字节等,有几点需要注意:

  1. S源位置的值 可以是立即数、寄存器中的值i或内存地址中的值,而D目的位置只能是寄存器或内存中的地址,不能是立即数

  2. 在x86-64中,S和D不能同时为内存中的地址

  3. movl(传送双字)如果目的地址位寄存器,会将该寄存器的高32位设置为0

movz、movs指令系列

这两类的指令都是在将较小的源值复制到较大的目的时使用,其源可以是内存或寄存器,目的只能是寄存器。并且每条指令最后都有两个字符,一个字符代表源大小(只有1,2字节),一个字符代表目的大小(2,4字),比如movzbl,movsbl

movz指令在复制时将目的的剩余位置用0填充。其格式类似为movz S,D,比如movzbl。

movs指令在复制时将目的的剩余位置用符号位填充。其格式类似为movz S,D

cltq指令只作用于eax和rax,其功能是将eax符号扩展到rax

入栈出栈操作

在编程中栈是非常有用的一种数据结构,在程序调用过程中栈也是非常有用的。汇编中有直接对栈的操作:

  1. pushq S 将四字压入栈 其效果是R[%rsp]<-R[%rsp]-8,M[R[%rsp]]<-S

  2. popq D 将四字从栈中弹出 其效果是D<-M[R[%rsp]],R[%rsp]<-R[%rsp]+8

所以pushq %rbp等价于

subq $8, %rsp
movq %rbp,(%rsp)

同理popq %rax等价于

movq (%rsp),%rax
addq $8,%rsp



参考资料

  1. 百度百科-机器语言

  2. 百度百科-汇编语言

  3. 豆瓣-深入理解计算机系统(原书第3版)



发布于: 2020 年 07 月 26 日 阅读数: 35
用户头像

引花眠

关注

还未添加个人签名 2018.06.11 加入

还未添加个人简介

评论

发布
暂无评论
程序的机器级表示-访问数据