计算机系统基础——上机作业2
实验1:变量输出与机器数分析
1.1 运行代码并分析输出
源代码:1
2
3
4
5
6
7
8
int main() {
int x = -1;
unsigned u = 2147483648;
printf("x = %u = %d.\n", x, x);
printf("u = %u = %d.\n", u, u);
return 0;
}
编译与运行:1
2gcc -o test1 test1.c
./test1
输出结果(假设32位系统):1
2x = 4294967295 = -1.
u = 2147483648 = -2147483648.
结果分析:
x = %u:x是int类型的-1,二进制补码为0xFFFFFFFF。用%u(无符号)解释时,0xFFFFFFFF对应4294967295。x = %d:
正常输出-1。u = %u:u是unsigned类型的2147483648(即0x80000000),直接输出为2147483648。u = %d:
用%d(有符号)解释0x80000000,最高位为1,表示负数,结果为-2147483648。
1.2 反汇编分析机器数
步骤:
- 生成目标文件:
1
gcc -c test1.c -o test1.o
- 反汇编查看变量赋值:
1
objdump -d -M intel test1.o
关键汇编代码(简化):1
2mov DWORD PTR [rbp-4], 0xffffffff ; x = -1 (机器数 0xFFFFFFFF)
mov DWORD PTR [rbp-8], 0x80000000 ; u = 2147483648 (机器数 0x80000000)
变量机器数总结:
| 变量 | 机器数(十六进制) |
| —— | ————————— |
| x | 0xFFFFFFFF |
| u | 0x80000000 |
实验2:表达式结果与反汇编分析
2.1 验证表达式结果
源代码:1
2
3
4
5
6
7
8
int main() {
printf("-1 < 0\t\t -> %d\n", (-1 < 0));
printf("-1 < 0U\t -> %d\n", (-1 < 0U));
printf("2147483647 > -2147483647 - 1\t -> %d\n", (2147483647 > -2147483647 - 1));
printf("2147483647U > -2147483647 - 1\t -> %d\n", (2147483647U > -2147483647 - 1));
return 0;
}
编译与运行:1
2gcc -o test2 test2.c
./test2
输出结果:1
2
3
4-1 < 0 -> 1
-1 < 0U -> 0
2147483647 > -2147483647 - 1 -> 1
2147483647U > -2147483647 - 1 -> 0
结果分析:
-1 < 0:
有符号比较,-1小于0,结果为真(1)。-1 < 0U:0U是无符号,-1被转换为无符号数0xFFFFFFFF(4294967295),远大于0U,结果为假(0)。2147483647 > -2147483647 - 1:
右侧表达式-2147483647 - 1等于-2147483648(INT_MIN),有符号比较,2147483647(INT_MAX)大于INT_MIN,结果为真(1)。2147483647U > -2147483647 - 1:
左侧是无符号,右侧INT_MIN被转换为无符号数0x80000000(2147483648),比较2147483647和2147483648,结果为假(0)。
2.2 反汇编分析表达式
步骤:
- 生成目标文件:
1
gcc -c test2.c -o test2.o
- 反汇编查看比较指令:
1
objdump -d -M intel test2.o
关键汇编代码(以 -1 < 0U 为例):1
2
3mov DWORD PTR [rbp-4], 0xffffffff ; -1 的机器数
cmp DWORD PTR [rbp-4], 0 ; 比较时,-1 被视为无符号数 4294967295
setb al ; 设置结果(0 表示假)
总结:
- 类型转换规则决定了比较结果。
- 反汇编显示编译器如何处理有符号与无符号的隐式转换。
实验报告建议
- 源代码与输出结果:附上代码及运行结果。
- 反汇编截图:展示变量赋值和表达式比较的汇编代码。
- 分析:
- 解释类型转换对输出的影响。
- 说明反汇编中机器数与表达式比较的底层实现。
如果需要更详细的反汇编代码或具体步骤解释,请随时告知!