CSAPP e3.4

练习题3.4

图1

题目中提到“当执行强制类型转换既涉及大小变化又涉及C语言中符号变化时,操作应该先改变大小”,我们通过一个例子来说明。

考虑下面这段代码

1
2
3
4
5
6
7
#include <stdio.h>
int main()
{
char a=0xff;
printf("%u",(unsigned)a);
return 0;
}

这里将 char 类型的变量转成 unsigned 类型,理论上有两种可能:一是转成 int 并进行符号扩展,然后转成unsigned,二是转成 unsigned char,然后转成 unsigned 并进行零扩展。程序的输出结果为 42949672954294967295,说明实际上是按照第一种方式进行的。这也符合题目中的表述,即先将类型变宽,再进行有无符号的变化。

那么考虑练习中的第二个和第三个例子。第二个例子的转换方式和上面一样,容易写出对应的汇编代码:

1
2
movsbl (%rdi),%eax
movl %eax,(%rsi)

第三个例子中先将 unsigned char 转成 unsigned 并进行零扩展,然后转成 long。这里利用了一个特性:当向寄存器写入双字时,会将高 44 字节置为 00。可以写出对应的汇编代码:

1
2
movzbl (%rdi),%eax
movq %rax,(%rsi)

CSAPP e3.4
https://je3ter.github.io/2024/02/17/CSAPP/CSAPP e3.4/
作者
Je3ter
发布于
2024年2月17日
许可协议