前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >程序机械级表示——数据格式与访问信息

程序机械级表示——数据格式与访问信息

作者头像
Andromeda
发布2023-10-21 11:33:49
2120
发布2023-10-21 11:33:49
举报
文章被收录于专栏:Andromeda的专栏

数据格式

8位称为字节(byte),16位称为字(word),32位为双字(double words),64位为四字(quad words)

C语言基本数据类型对应的x86-64表示如下

C声明

Intel数据类型

汇编代码后缀

大小(byte)

char

字节

b

1

short

w

2

int

双字

l

4

long

四字

q

8

char *

四字

q

8

float

单精度

s

4

double

双精度

l

8

大多数GCC生成的汇编代码指令都有一个字符的后缀,表明操作数的大小。例如movb、mobw等等。l后缀可同时表示双字和双精度,因为浮点数使用的是一组完全不同的指令和寄存器,因此不会产生歧义。

访问信息

寄存器

一个x86-64的CPU包含一组16个存储64位值的通用寄存器,用于存储整数和指针。初始的8086有8个16位的寄存器,如下标的%ax到%sp。扩展到IA32架构时,这些寄存器也扩展到了32位寄存器,从%eax到%esp。

63

31

15

7

%rax

%eax

%ax

%al

返回值

%rbx

%ebx

%bx

%bl

被调用者保存

%rcx

%ecx

%cx

%cl

参数4

%rdx

%edx

%dx

%dl

参数3

%rsi

%esi

%si

%sil

参数2

%rdi

%edi

%di

%dil

参数1

%rbp

%ebp

%bp

%bpl

被调用者保存

%rsp

%esp

%sp

%spl

栈指针

%r8

%r8d

%r8w

%r8b

参数5

%r9

%r9d

%r9w

%r9b

参数6

%r10

%r10d

%r10w

%r10b

调用者保存

%r11

%r11d

%r11w

%r11b

调用者保存

%r12

%r12d

%r12w

%r12b

被调用者保存

%r13

%r13d

%r13w

%r13b

被调用者保存

%r14

%r14d

%r14w

%r14b

被调用者保存

%r15

%r15d

%r15w

%r15b

被调用者保存

指令可以通过上表中嵌套的寄存器表示对这十六个寄存器的低位字节进行操作。复制和生成1字节、2字节、4字节、8字节值。当以这些寄存器作为目标时,有这样的规则:生成1字节和2字节数时保持高位剩下的字节不变,生成四字节数时会把高位四字节置为0。

寻址

操作数的寻址可以分为三种类型——立即数、寄存器和内存引用。如下表所示

类型

格式

操作数值

名称

立即数

$Imm

Imm

立即数寻址

寄存器

ra

R[ra]

寄存器寻址

存储器

Imm

M[Imm]

绝对寻址

存储器

(ra)

M[R[ra]]

间接寻址

存储器

Imm(rb)

M[Imm + R[rb]]

基址寻址

存储器

(rb, ri)

M[R[ra] + R[rb]]

变址寻址

存储器

Imm(rb, ri)

M[Imm + R[ra] + R[ri]]

变址寻址

存储器

(, ri, s)

M[R[ri] * s]

比例变址寻址

存储器

Imm(, ri, s)

M[Imm + R[ri] * s]

比例变址寻址

存储器

(rb, ri, s)

M[R[rb] + R[ri] * s]

比例变址寻址

存储器

Imm(rb, ri, s)

M[Imm + R[rb] + R[ri] * s]

比例变址寻址

数据传送

最简单的数据传送指令是MOV类,movb、movw、movl、movq这四条指令执行相同的操作,不同的是他们的操作数的大小不同

指令

效果

描述

MOV S, D

D<—S

传送

movb

传送字节

movw

传送字

movl

传送双字

movq

传送四字

movabsq I, R

R<—I

传送绝对的四字

源操作数指定的值是一个立即数,存储在寄存器或者内存中。目的操作数指定一个位置,要么是一个寄存器,要么是一个内存地址。x86-64增加了一条限制,两个操作数不能都指向内存位置,要将一个值从内存中的一个位置复制到另一个位置必须先将源值加载到寄存器,然后再写入目的内存地址。

常规的movq指令只能以表示为32位补码数字的立即数作为源操作数,然后把该值符号扩充得到64位的值并放到目标位置。movabsq指令能够以任意64位立即数作为源操作数,并且只能以寄存器作为目的。

在将较小的源值复制到较大的目的地时使用movz或者movs指令。

MOVZ类中的指令把剩余的字节填充为0,MOVS则填充为源操作数的最高位。两种指令格式为mov[z/s + 后缀1 + 后缀2],即第一个后缀为源操作数的大小,第二个后缀为目的地址的大小。

MOVS类中还给出了cltq指令。cltq指令没有操作数,他总以寄存器%eax作为源,%rax作为符号扩展结果的目的,也就是等效于movslq %eax, %rax,不过编码更紧凑。

数据传送实例

C语言代码如下

代码语言:javascript
复制
long swap(long *des, long src)
 {
     long tmp = *des;
     *des = src;
     return tmp;
 }

产生的汇编代码如下,%rdi为参数一即des,%rsi为参数二src,%rax为返回值

代码语言:javascript
复制
swap:
  movq (%rdi), %rax
  movq %rsi, (%rdi)
  ret

上面的汇编代码将%rdi中的指针des作为地址在内存中寻址,并将des指针指向的值传输到返回值%rax中即tmp。由于long类型为4字,因此使用movq。第三行同理,将%rsi寄存器中的值直接传输到%rdi寄存器中的指针des指向的内存地址,最后返回结果。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 数据格式
  • 访问信息
    • 寄存器
      • 寻址
        • 数据传送
        • 数据传送实例
        相关产品与服务
        对象存储
        对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档