计算机系统基础第四次作业及练习题
3.63


- 首先我们查看switch部分的第一代码:
sub $0x3c,%rsi%rsi-=60; 我们可以知道跳转表中第一个位置对应的数即为60,且跳转表中一共有6个地址,则switch中最大的数应该为65 - 然后我们根据
ja 4005c3当%rsi>5时,就跳转到地址4005c3所以该地址应该为default 的地址。 - 最后我们把每个地址中的汇编代码转化为c代码。
0x4005a1:
1
2result*=8;
return result;0x4005c3:
1
2result+=75;
return result;0x4005aa:
1
return result>>3;0x4005b2:
1
2
3
4result =<< 4;
result -= x;
result*=result;
return result+75;0x4005bf:
1
2result*=result;
return result+75;
这样我们就得到了完整的函数c代码:
1 | |
3.66

这一题需要我们反向计算出NR(n)和NC(n)的值,根据题目已知信息该函数计算矩阵的j列的和。我们分析汇编代码的前几行代码:
1 | |
以及L4的代码:
1 | |
当 %rax <=0时,就不会进入循环,这里的 %rax = 3*n 就是NR(n)的定义,所以得到:
1 | |
然后我们看循环内部的代码:
1 | |
我们可以知道 %rcx 存储的即为每一行 j 列元素的地址,%rax为result。由于c语言中二维数组以行为主序,所以 %8 就是NC(n) 的定义。%r8 = (4n+1)*8 8为long 类型的宽度。所以NC的定义为:
1 | |
3.64

等式(3. 1)如图所示, 假设数组D的定义为D[R][S][T],则D[i][j][k] 的地址为:
A:&D[i][j][k] = D + L*( T*(S*i + j) + k)
B:
1 | |
根据A推出的公式,得到:
- S = 5
- T = 13
- R = 3640 /8/65 = 7
3.69


A.
第一句汇编代码 mov 0x120(%rsi),%esi 我们根据b_struct的声明可以得知 bp->last 的地址为 bp + 288;
由于由于 bp->a 的首地址为:bp + 8 所以 bp->a 所占的空间为280个字节。
通过
1 | |
我们可以知道a的一个结构体所占的空间为40个字节,所以我们可以得到:
- CNT = 280 / 40 = 7
B.
我们看剩下的汇编代码:
1 | |
我们可以得知a_struct中,第一个元素 idx 占16个字节,x 是个数组,每个元素占8个字节,结合题目所存取的数都是有符号数。所以我们得到a_struct 的完整声明如下:
1 | |
练习题
3.1

答案:

3.2

在写后缀时,似乎是在两个操作数中选取小的那个操作数的大小作为赋值的大小
- movl %eax 大小4个字节,所以为双字 l
- movw %dx 大小为2个字节,所以为单字w
- movb $0xFF 为一个字节,为一个字节b
- movb %dl 大小为一个字节,为b
- movq 两个操作数都为四字,为q
- movw %dx为字,为w
3.3

- %ebx 只有寄存器前4个字节的信息, 但是64位机器中内存中地址需要8个字节表示。
- movl只能赋值4个字节的信息,%rax和(%rsp)有8个字节长,指令后缀与寄存器ID不匹配
- 源和目的不能都是内存
- 没有寄存器 %sl
- 无法把一个立即数当作目标
- 目标地址的大小不正确
- 指令后缀与寄存器id不匹配,%si为双字,b表示一个字节的赋值
3.4

在小到大的转化时,我们通过指令movz类或movs类来进行:movz进行无符号扩充,movs进行有符号扩充;
在大到小的转化中,我们直接使用 mov类,截断高位数据。
char -> int
1
2movsbl (%rdi),%eax
movl %eax, (%rsi)char ->unsigned
1
2movzbl (%rdi),%eax
movl %eax, (%rsi)unsigned char -> long(应该维持原先的无符号数的值不变)
1
2movzbl (%rdi),%eax //读一个字节并进行0扩位
movq %rax,(%rsi)int -> char
1
2movl (%rdi),%eax
movb %al,(%rsi)unsigned -> unsigned char
1
2movl (%rdi),%eax
movb %al,(%rsi)char -> short
1
2movsbw (%rdi),%ax
movw %ax,(%rsi)
3.6

- x +6 (题目有误,%ax应为 %rax)
- x + y
- x + y*4
- x + 8*x + 7 = 9 *x +7
- 4*y + 10
- x + y * 2 +9
2.21

如果有任何一个运算数是无符号的,那么在比较之前,另一个运算数会被强制类型转换为无符号数。
| 类型 | 求值 |
|---|---|
| 无符号 | 1 |
| 有符号 | 1 |
| 无符号 | 0 |
| 有符号 | 1 |
| 无符号 | 1 |
- 第一个数为-2147483648 转为无符号数为2147483648 == 2147483648 所以求值为1
- 第一个数-2147483648 ,第二个数为2147483647 两侧都为有符号数,求值为1
- 第一个数为-2147483648,转为无符号数为2147483648,因该>2147483647 求值为 0
- 第一个数为-2147483648,第二个数为-2147483647,都为有符号数直接求值为1
- 第一个数为-2147483648,转为无符号数为2147483648,第二个数为-2147483647,转为无符号数为2147483649 > 2147483648 所以求值为 1
2.23

首先我们先将每个函数执行后的二进制码写出来:
| w | fun1(w) | fun2(w) |
|---|---|---|
| 0x00000076 | 0x00000076 | 0x00000076 |
| 0x87654321 | 0x00000021 | 0x00000021 |
| 0x000000C9 | 0x000000C9 | 0xFFFFFFC9 |
| 0xEDCBA987 | 0x00000087 | 0xFFFFFF87 |
然后我们再把他们转化成10进制整数:
| w | fun1(w) | fun2(w) |
|---|---|---|
| 0x00000076 | 118 | 118 |
| 0x87654321 | 33 | 33 |
| 0x000000C9 | 201 | -55 |
| 0xEDCBA987 | 135 | -121 |
2.24

首先来看无符号数:无符号数的截断与16进制直接截断相同
| 原始值 | 截断值 |
|---|---|
| 0(%8) | 0 |
| 2(%8) | 2 |
| 9(%8) | 1 |
| 11(%8) | 3 |
| 15(%8) | 7 |
然后来看有符号数:
| 原始值 | 截断值 |
|---|---|
| 0->0(%8) | 0 |
| 2->2(%8) | 2 |
| (-7)-> 9(%8) | 1 |
| -5->11(%8) | 3 |
| -1->15(%8) = 7 (-2^4) | -1 |
等式(2. 9):

等式(2.10):

2.33

| 16进制 | 10进制 | 10进制 | 16进制 |
|---|---|---|---|
| 0 | 0 | 0 | 0 |
| 5 | 5 | -5 | B |
| 8 | -8 | 8 | 8 |
| D | -3 | 3 | 3 |
| F | -1 | 1 | 1 |
通过16进制观察可能不明显:我们把左右两列变成2进制观察:
| col1 | col2 |
|---|---|
| 0000 | 0000 |
| 0101 | 1011 |
| 1000 | 1000 |
| 1101 | 0011 |
| 1111 | 0001 |
加法逆元的的二进制位等于取反+1,使得a + (-a) 后刚好进位溢出1,使得有效位全部为0。
2.40

| 表达式 |
|---|
| (x<<2) + (x<<1) |
| (x<<5) - x |
| (x <<1) - (x<<3) |
| (x<<6) - (x<<3) -x |
2.45

| 小数值 | 二进制表示 | 十进制表示 |
|---|---|---|
| 1/8 | 0.001 | 0.125 |
| 3/4 | 0.11 | 0.75 |
| 25/16 | 1.1001 | 1.5625 |
| 43/16 | 10.1011 | 2.6876 |
| 9/8 | 1.001 | 1.125 |
| 47/8 | 101.111 | 5.875 |
| 51/16 | 11.0011 | 3.1875 |
2.47

| 位 | e | E | 2^E | f | M | (2^E) * M | V | 十进制 |
|---|---|---|---|---|---|---|---|---|
| 0 00 00 | 0 | 0 | 1 | 0/4 | 0/4 | 0/4 | 0 | 0 |
| 0 00 01 | 0 | 0 | 1 | 1/4 | 1/4 | 1/4 | 1/4 | 0.25 |
| 0 00 10 | 0 | 0 | 1 | 2/4 | 2/4 | 2/4 | 1/2 | 0.5 |
| 0 00 11 | 0 | 0 | 1 | 3/4 | 3/4 | 3/4 | 3/4 | 0.75 |
| 0 01 00 | 1 | 0 | 1 | 0 | 1 | 1 | 1 | 1.0 |
| 0 01 01 | 1 | 0 | 1 | 1/4 | 5/4 | 5/4 | 5/4 | 1.25 |
| 0 01 10 | 1 | 0 | 1 | 2/4 | 6/4 | 6/4 | 3/2 | 1.5 |
| 0 01 11 | 1 | 0 | 1 | 3/4 | 7/4 | 7/4 | 7/4 | 1.75 |
| 0 10 00 | 2 | 1 | 2 | 0 | 1 | 2 | 2 | 2.0 |
| 0 10 01 | 2 | 1 | 2 | 1/4 | 5/4 | 5/2 | 5/2 | 2.5 |
| 0 10 10 | 2 | 1 | 2 | 2/4 | 6/4 | 6/2 | 3 | 3.0 |
| 0 10 11 | 2 | 1 | 2 | 3/4 | 7/4 | 7/2 | 7/2 | 3.5 |
| 0 11 00 | – | – | – | – | – | – | 正无穷 | – |
| 0 11 01 | – | – | – | – | – | – | NaN | – |
| 0 11 10 | – | – | – | – | – | – | NaN | – |
| 0 11 11 | – | – | – | – | – | – | NaN | – |