1. Intel X86-64 (即x64) 位CPU中,有哪些通用的64位寄存器?通用的32位的寄存器?通用的16位寄存器?通用的8位寄存器?(只需要列出符号名即可,不用给出寄存器的中文名称)
64位:rax、rbx、rcx、rdx、rbp、rsi、rdi、rsp、r8、 r9、 r10、r11、r12、r13、r14、r15
32位:eax、ebx、ecx、edx、ebp、esi、edi、esp、r8d -- r15d
16位:ax、 bx、cx、dx、bp、si、di、sp、r8w -- r15w
8位:al、bl、cl、dl、bpl、sil、dil、spl、r8b -- r15b
2. Intel X86-64 CPU中,64位的指令指示器 RIP 中存放的是什么?程序运行的基本过程是什么?(包含RIP是何时变化的)
保存着下一条将要被CPU执行的指令的偏移地址;
程序运行的基本过程是:取指令、指令译码、取操作数、执行、写回。在当前指令执行完毕后,RIP的值会根据指令的跳转或分支条件进行更新。
3. 编译器在生成执行程序时,可以做哪些优化工作?为什么做相应的工作可以提高程序的执行速度?
优化指令顺序;
这样可以减少指令间相关性、改善局部性从而减少内存访问时间、减少流水线停顿时间。
4. 已知8位二进制数x1和x2的值,请写出 [x1]补、[x2]补 各是多少?[x1]补+[x2]补 后的结果是多少?以及标志位 SF、ZF、CF、OF 各是多少?
x1=+0110011B; x2=+1011010B
[x1]补 = 00110011,[x2]补 = 01011010
[x1]补+[x2]补 = 10001101
SF = 1, ZF = 0, OF = 1, CF = 0
x1=-0101001B; x2=-1011101B
[x1]补 = 11010111, [x2]补 = 10100011
[x1]补+[x2]补 = 01111010
SF = 0, ZF = 0, OF = 1, CF = 1
x1=+1100101B; x2=-1011101B
[x1]补 = 01100101, [x2]补 = 10100011
[x1]补+[x2]补 = 00001000
SF = 0, ZF = 0, OF = 0, CF = 1
5、对如下 C语言程序,用VS2019(Intel CPU,x86-debug)编译、链接、调试运行。
int main( )
{
int a = 100; //0x64
int b = 0x12345678;
int r = 0;
char msg[6] = "abcde"; // 'a'的ASCII是 0x61
return 0;
}
在return处设置断点调试时,在监视窗口中看到变量 a 的地址(即&a)为 0x010ffe98;变量 b 的地址(即&b) 为 0x010ffe94;变量 r 的地址为 0x010ffe90, 数组 msg 的起始地址为 0x010ffe88。
以字节为单位、用16进制数的形式填空,最左边是内存窗口显示的内存地址。
0x010ffe88 __61___ __62___ __63___ __64___ __65___ __00___ XX XX
0x010ffe90 __00___ __00___ __00___ __00___ __78___ __56___ __34___ __12___
0x010ffe98 __64___ __00___ __00___ __00___ XX XX XX XX
6、整数数据的表示
设有 short x; 除了 x = 0外,x有无其他值使得 x == -x?该值是多少?说明理由。
存在, x = -32768,因为此时x 和 -x 的机内存储都是0x8000,均被解释为-32768。
7、有符号数与无符号数
设有 short x = 0xf100; short y = 0x1234; 问 x > y 是否成立?说明理由。
设有 unsigned short u = 0xf100; unsigned short v = 0x1234; 问 u > v 是否成立?说明理由。
x > y 不成立,因为x、y是有符号数,x被解释为负数的补码,而y是正数的补码。
u > v 成立,因为x、y都是无符号数,直接比较大小。
8、数据类型转换
设有 int x; float y; y = (float)x;
问 x == (int)y 是否(一定)成立,为什么?
若有 x =(int) y; y ==(float) x; 是否(一定)成立,为什么?
x == (int)y 不一定成立,因为int与float在整数区域仅部分重叠,可能会出现精度损失和舍入误差。
若有 x =(int) y; y ==(float) x;也不一定成立,因为同样可能出现精度损失和舍入误差。
9、字符串的表示
设有 char s[] = ”…”; 在内存中观察数组s中存放的信息为 :
31 32 33 67 6f 6f 64 00 (每个字节都是16进制数,31对应的字节地址最小)。
问 char s[] = ”…”,引用中的字符串是什么?
123good
10、浮点数的表示
给出 11.25 的单精度浮点表示(要分别给出符号位、指数部分、有效数部分的编码),以及该数在内存中的存放形式。
[11.25]2 = 1011.01 = (-1)^0 + 2^(130 – 127) + 1.01101
故S = 0, E = 10000010, M = 01101
单精度浮点表示为:0100 0001 0011 0100 0000 0000 0000 0000
内存中存放形式为:00 00 34 41
11、为什么float数有+0和-0?如何判断一个float变量的值是 +0还是-0?
其余位相同,S位分别取0和1,造成了有+0和-0。
判断方法:可以通过观察内存判断,或者输出printf("%d\n", *((char*)&x + 3));来判断,对于这个语句+0输出是0,-0输出是-128。
12、假设:
float a = 65536; //0x10000
float b;
求满足 b>a 的条件下, IEEE754能表示的最小 b。
满足该条件的浮点数的IEEE754表示为:0100 0111 1000 0000 0000 0000 0000 0001。
转换成十进制为(-1)^0 * 2^16 * (1 + 2^(-23)) = 65536.0078125