题目条件
src_t *sp; dest_t *dp;
sp和dp的值分别存储在寄存器%rdi和寄存器%rsi中,表中每个表项应实现两条指令,第一条是从内存中读数,做适当的转换,并设置寄存器%rax的适当部分。第二条指令是要把%rax的适当部分写到内存。在这两种情况下,寄存器的部分可以是%rax,%eax,%ax或%al。
当执行强制类型转换既涉及大小变化又涉及C语言中符号变化时,操作应先改变大小
要求实现: *dp = (dest_t)*sp;
src_t | dest_t | 指令 |
---|---|---|
long | long | |
char | int | |
char | unsigned | |
unsigned char | long | |
int | char | |
unsigned | unsigned char | |
char | short |
这个转换比较繁琐,但是根据csapp书上图3-4、图3-5、图3-6的知识点就能完成相应的转换,下面来一行一行的进行推导
1.long --> long
long是8个字节,8个字节的转换用movq,存储器是64位,所以用%rax。
读取8字节:movq (%rdi), %rax
存储8字节:movq %rax, (%rsi)
2.char --> int
char是1个字节,int是4个字节,并且是有符号数,进行符号扩展,movs是符号扩展,由于要扩展到4字节,所以用movsbl。4个字节的存储器用%eax。
读1个字节并进行符号扩展:movsbl (%rdi), %eax
存储4字节:movl %eax, (%rsi)
3.char --> unsigned
char是1个字节,unsigned是4个字节,已知当执行强制类型转换既涉及大小变化又涉及C语言中符号变化时,操作应先改变大小,所以先将char转换为int,选择符号扩展,存储器选用%eax。
读1个字节并进行符号扩展:movsbl (%rdi), %eax
存储4字节:movl %eax, (%rsi)
4.unsigned char --> long
unsigned char是1个字节,long是8个字节,应先改变大小,将char转换为long,由于char是无符号数,所以进行零扩展,选择movzbq,存储器选择%rax。
读1个字节并进行零扩展:movzbq (%rdi), %rax
存储8字节:movq %rax, (%rsi)
这道题第一条指令的答案是movzbl (%rdi), %eax,之前上网查好像是与cpu有关,但是我没太弄懂,感觉按原理来说应该是我上面的答案
5.int --> char
int是4个字节,char是1个字节,所以先将int的值从内存复制到存储器中,在从存储器中存低位字节即可。
读4个字节:movl (%rdi), %eax
存低位字节:movb %al, (%rsi)
6.unsigned --> unsigned char
这个与第五个是一样的原理,就不复述了。
读4个字节:movl (%rdi), %eax
存低位字节:movb %al, (%rsi)
7.char --> short
char是1个字节,short是2个字节,由于是有符号数,所以进行符号扩展,存储器选择%ax。
读1个字节并进行符号扩展:movsbw (%rdi), %ax
存两个字节:movw %ax, (%rsi)