辅助学习的方法,提升效率的3步走。
- 记笔记
- 画内存图
- 逐条注释指令
解题过程
- 首先,读题干并理解目的,目的是将指针dp所指令的内存数据,用sp所指向的内存数据进行替换,并进行格式转换(所谓格式转换,就是告诉计算机此指针指向的数据类型,它约束了内存单元的数量,比如同样指向了地址A,它只 是第1个内存单元的地址,向后包括多少个单元,是由类型决定的)
- 示例中的指令分析
movq (%rdi),%rax
指令解析,将%rdi
中存储的内存地址对应的内存中的数据,给到寄存器%rax
,大小是一个qword
的long
类型,取值范围在本书中指4个byte大小movq %rax, (%rsi)
,将寄存器%rax
中的值,存储到内存区域(地址为%rsi
中的值)- 整个过程中,读取和写入都是
long
类型,不涉及类型转换
- 第2问,
char
到int
- 将1byte写入到2byte的内存中,涉及到高位置0,因本题是涉及符号(即有正负之分),所以要使用
sign extended
movs
,而不能使用zero extended
的movz
- 第1句
movsbl (%rdi), %eax
,这里其实是向%eax
的低位字节写入了1个byte,并以有符号形式扩展高位字节。注意,这里使用的是%eax
,而非8字节(4字)的%rax
- 第2句,
movl %eax, (%rsi)
,与上一例中一样,将4个字的数据写入到dp即%rdi
所指向或者说所存储的内存地址中
- 将1byte写入到2byte的内存中,涉及到高位置0,因本题是涉及符号(即有正负之分),所以要使用
- 第3问,
char
到unsigned
- 将1字节写入无符号的4字节
movzbl (%rdi),%eax
,既然说明了是unsigned
,转换时使用零扩展方式即可,低字节写入1字节的数据,高字节用0
填充movl %eax,(%rsi)
,将写入后并填充后的数据,复制到目标位置,这里注意一下写入数据的字节数量,使用movl
而非movq
- 第4问,
unsigned char
到long
movzbq (%rdi),%rax
movq %rax,(%rsi)
- 第5问,
int
tochar
movb (%rdi),%al
,针对多字节类型
向少字节类型
写入时,只需要动用小型寄存器movb %al,(%rsi)
- 第6问,
unsinged
tounsigned char
movb (%rdi),%al
movb %al,(%rsi)
- 第7问,
char
toshort
- 由单字节到单字(双字节)
movsbw (%rdi),%ax
movw %ax,(%rsi)
需注意几点
- 将
少字节类型
向多字节类型
写入,涉及高位填充,而填充又分为零扩展和符号扩展 - 将
多字节类型
向少字节类型
写入,需要动用小规模寄存器,如%al
- 目标内存处的数据类型所占字节大小,决定了中转寄存器应该选择
%rax,%eax,%al
中的哪个%al
,1byte%ax
,1word=2bytes%eax
,2words = 4bytes%rax
,4words = 8bytes
解题思路总结
- 先确定待写入目标数据(要写入到目标内存中的数据)占几个字节,据此决定选择多大的寄存器,如
%rax,%eax,%ax,%al
等 - 确定源数据与目标数据之间的大小关于
- 如果是小数据类型向大数据类型写入,则涉及高位填充(zero extended or sign extended)
- 如果是大数据类型向小数据类型写入,则直接使用对应大小的寄存器从源数据中取出对应低位部分的数据