1. 给出以下概念的解释说明。
第 二 章 习 题 答 案
数值数据
补码
阶码
右规
机器数
真值
原码
定点数
尾数
阶
规格化数 左规
BCD 码 逻辑数
ASCII 码 汉字输入码 汉字内码
大端方式 小端方式 最高有效位 最高有效字节(MSB)
最低有效字节(LSB)
符号扩展 零标志 ZF 溢出标志 OF 符号标志 SF 进位/借位标志 CF
非数值数据 无符号整数
变形补码
移码
非规格化数 机器零
溢出
阶码下溢
机器字长
逻辑移位
带符号整数
浮点数
阶码上溢
非数(NaN)
最低有效位
0 扩展
掩码
算术移位
2. 简单回答下列问题。
(1)为什么计算机内部采用二进制表示信息?既然计算机内部所有信息都用二进制表示,为什么还要
用到十六进制或八进制数?
(2)常用的定点数编码方式有哪几种? 通常它们各自用来表示什么?
(3)为什么现代计算机中大多用补码表示带符号整数?
(4)在浮点数的基数和总位数一定的情况下,浮点数的表示范围和精度分别由什么决定?两者如何相
互制约?
(5)为什么要对浮点数进行规格化?有哪两种规格化操作?
(6)为什么有些计算机中除了用二进制外还用 BCD 码来表示数值数据?
(7)为什么计算机处理汉字时会涉及到不同的编码(如,输入码、内码、字模码)?说明这些编码中
哪些用二进制编码,哪些不用二进制编码,为什么?
3.实现下列各数的转换。
(1) (25.8125)10= (?)2= (?) 8= (?) 16
(2) (101101.011)2 = (?)10= (?) 8= (?) 16= (?) 8421
(3) (0101 1001 0110.0011)8421 = (?)10= (?) 2= (?) 16
(4) (4E.C)16 = (?)10= (?) 2
参考答案:
(1) (25.8125)10 = (1 1001.1101)2 = (31.64) 8 = (19.D) 16
(2)(101101.011)2 = (45.375)10 = (55.3) 8 = (2D.6) 16 = (0100 0101.0011 0111 0101) 8421
(3)(0101 1001 0110.0011)8421 = (596.3)10 = (1001010100.01001100110011…) 2 = (254.4CCC…) 16
(4)(4E.C)16 = (78.75)10 = (0100 1110.11) 2
4. 假定机器数为 8 位(1 位符号,7 位数值),写出下列各二进制数的原码表示。
+0.1001,–0.1001,+1.0,–1.0,+0.010100,–0.010100,+0,–0
参考答案:
(后面添 0)
原码
0.1001000
1.1001000
溢出
溢出
0.0101000
1.0101000
0.0000000
1.0000000
+0.1001:
–0.1001:
+1.0:
–1.0:
+0.010100:
–0.010100:
+0:
–0:
5. 假定机器数为 8 位(1 位符号,7 位数值),写出下列各二进制数的补码和移码表示。
+1001,–1001,+1,–1,+10100,–10100,+0,–0
参考答案:(假定移码的偏置常数为 128)
(前面添 0)
+1001:
–1001:
+1:
–1:
+10100:
–10100:
+0:
–0:
6. 已知 [x]补,求 x
移码
10001001
01110111
10000001
011111111
10010100
01101100
10000000
10000000
补码
00001001
11110111
00000001
11111111
00010100
11101100
00000000
00000000
(3)[x]补=01010010 (4)[x]补=11010011
(1)[x]补=11100111 (2)[x]补=10000000
参考答案:
(1)[x]补=11100111
(2)[x]补=10000000
(3)[x]补=01010010
(4)[x]补=11010011
x = –0011001B = –25
x = –10000000B = –128
x = +1010010B = 82
x = – 0101101B = – 45
7. 某 32 位字长的机器中带符号整数用补码表示,浮点数用 IEEE 754 标准表示,寄存器 R1 和 R2 的内
容分别为 R1:0000108BH,R2:8080108BH。不同指令对寄存器进行不同的操作,因而不同指令执
行时寄存器内容对应的真值不同。假定执行下列运算指令时,操作数为寄存器 R1 和 R2 的内容,则
R1 和 R2 中操作数的真值分别为多少?
(1) 无符号整数加法指令
(2) 带符号整数乘法指令
(3) 单精度浮点数减法指令
参考答案:
(1)对于无符号数加法指令,R1 和 R2 中是操作数的无符号数表示,因此,其真值分别为 R1:108BH,
R1 = 0000108BH = 0000 0000 0000 0000 0001 0000 1000 1011B
R2 = 8080108BH = 1000 0000 1000 0000 0001 0000 1000 1011B
R2:8080108BH。
(2)对于带符号整数乘法指令,R1 和 R2 中是操作数的带符号整数,即补码表示,由最高位可知,
R1 为正数, R2 为负数。R1 的真值为+108BH,R2 的真值为–(111 1111 0111 1111 1110 1111 0111
0100b + 1b) = –7F7FEF75H。
(3)对于单精度浮点数减法指令,R1 和 R2 中是操作数的 IEEE 754 单精度浮点数表示。在 IEEE 754
标准中,单精度浮点数的位数为 32 位,其中包含 1 位符号位,8 位阶码,23 位尾数。
由 R1 中的内容可知,其符号位为 0,说明为正数,阶码为 0000 0000,尾数部分为 000 0000 0001
0000 1000 1011,故其为非规格化浮点数,指数为–126,尾数中没有隐藏的 1,用十六进制表示
尾数为+0.002116H,故 R1 表示的真值为+0.002116H × 2-126。
由 R2 中的内容可知,其符号位为 1,表示其为负数,阶码为 0000 0001, 尾数部分为 000 0000 0001
0000 1000 1011,故其为规格化浮点数,指数为 1–127 = –126,尾数中有隐藏的 1,用十六进制
表示尾数为–1.002116H,故 R2 表示的真值为–1.002116H × 2-126
8. 假定机器 M 的字长为 32 位,用补码表示带符号整数。表 2.12 中第一列给出了在机器 M 上执行的 C
语言程序中的关系表达式,请参照已有的表栏内容完成表中后三栏内容的填写。
关系表达式
0 == 0U
–1 < 0
–1 < 0U
2147483647 > –2147483647 – 1
2147483647U > –2147483647 – 1
2147483647 > (int) 2147483648U
–1 > –2
(unsigned) –1 > –2
参考答案:
关系表达式
0 == 0U
–1 < 0
–1 < 0U
2147483647 > –2147483647 – 1
2147483647U > –2147483647 – 1
2147483647 > (int) 2147483648U
–1 > –2
(unsigned) –1 > –2
表 2.12 题 8 用表
结果
运算类型
说明
无符号整数
有符号整数
0
1
11…1B (232–1) > 00…0B(0)
011…1B (231–1) > 100…0B (–231)
运算类型
无符号整数
有符号整数
无符号整数
有符号整数
无符号整数
有符号整数
有符号整数
无符号整数
结果
说明
1
1
0
1
0
1
1
1
00…0B = 00…0B
11…1B (–1) < 00…0B (0)
11…1B (232–1) > 00…0B(0)
011…1B (231–1) > 100…0B (–231)
011…1B (231–1) < 100…0B(231)
011…1B (231–1) > 100…0B (–231)
11…1B (–1) > 11…10B (–2)
11…1B (232–1) > 11…10B (232–2)
9. 在 32 位计算机中运行一个 C 语言程序,在该程序中出现了以下变量的初值,请写出它们对应的机器
(3)unsigned z=65530
(6)double b=10.5
数(用十六进制表示)。
(1)int x=-32768 (2)short y=522
(4)char c=’@’
(5)float a=-1.1
参考答案:
(1)-215=-1000 0000 0000 0000B,故机器数为 1…1 1000 0000 0000 0000=FFFF8000H
(2)522=10 0000 1010B,故机器数为 0000 0010 0000 1010=020AH
(3)65530=216-1-5=1111 1111 1111 1010B,故机器数为 0000FFFAH
(4)’@’的 ASCII 码是 40H
(5)-1.1=-1.00011 [0011]…B=-1.000 1100 1100 1100 1100 1100B,阶码为 127+0=01111111,故机器
数为 1 01111111 000 1100 1100 1100 1100 1100=BF8CCCCCH
(6)10.5=1010.1B=1.0101B23,阶码为 1023+3=100 0000 0010,故机器数为 0 100 0000 0010 0101
[0000]=40250000 00000000H
10. 在 32 位计算机中运行一个 C 语言程序,在该程序中出现了一些变量,已知这些变量在某一时刻的机
器数(用十六进制表示)如下,请写出它们对应的真值。
(1)int x:FFFF0006H (2)short y:DFFCH
(4)char c:2AH
参考答案:
(1)FFFF0006H=1…1 0000 0000 0000 0110B,故 x= -1111 1111 1111 1010B= -(65535-5)=-65530
(2)DFFCH=1101 1111 1111 1100B=-010 0000 0000 0100B
5)float a:C4480000H (6)double b:C024800000000000H
(3)unsigned z:FFFFFFFAH
故 y=-(8192+4)=-8196
(3)FFFFFFFAH=1…1 1010B,故 z=232-6
(4)2AH=0010 1010B,故 c=42,若 c 表示字符,则 c 为字符’*’
(5)C4480000H=1100 0100 0100 1000 0…0B,阶码为 10001000,阶为 136-127=9,尾数为-1.1001B,
故 a=-1.1001B29= -11 0010 0000B= -800
(6)C024800000000000H=1100 0000 0010 0100 1000 0 0…0B,阶码为 100 0000 0010,阶为
1026-1023=3,尾数为 1.01001B,故 b = -1.01001B23 = -1010.01B = -10.25
11. 以下给出的是一些字符串变量在内存中存放的字符串机器码,请根据 ASCII 码定义写出对应的字符
串。指出代码 0AH 和 00H 对应的字符的含义。
(1)char *mystring1:68H 65H 6CH 6CH 6FH 2CH 77H 6FH 72H 6CH 64H 0AH 00H
(2)char *mystring2:77H 65H 20H 61H 72H 65H 20H 68H 61H 70H 70H 79H 21H 00H
参考答案:
字符串由字符组成,每个字符在内存中存放的是对应的 ASCII 码,因而可根据表 2.5 中的 ASCII 码
和字符之间的对应关系写出字符串。
(1)mystring1 指向的字符串为:hello,world\n
(2)mystring2 指向的字符串为:we are happy!
其中,ASCII 码 00001010B=0AH 对应的是“换行”字符’\n’(LF)。每个字符串在内存存放时最后都
会有一个“空”字符’\0’(NUL),其 ASCII 码为 00H。
12. 以下给出的是一些字符串变量的初值,请写出对应的机器码。
(1)char *mystring1="./myfile"
参考答案:
(1)mysring1 指向的存储区存放内容为:2EH 2FH 6DH 79H 66H 69H 6CH 65H 00H
(2)mysring2 指向的存储区存放内容为:4FH 4BH 2CH 67H 6FH 6FH 64H 21H 00H
(2)char *mystring2="OK, good!"
13. 已知 C 语言中的按位异或运算(“XOR”)用符号“^”表示。对于任意一个位序列 a,a^a=0,C 语言程
序可以利用这个特性来实现两个数值交换的功能。以下是一个实现该功能的 C 语言函数:
1 void xor_swap(int *x, int *y)
2 {
3
4
5
6 }
/* 第一步 */
/* 第二步 */
/* 第三步 */
*y=*x ^ *y;
*x=*x ^ *y;
*y=*x ^ *y;
假定执行该函数时*x 和*y 的初始值分别为 a 和 b,即*x=a 且*y=b,请给出每一步执行结束后,x 和 y
各自指向的内存单元中的内容分别是什么?
参考答案:
第一步结束后,x 和 y 指向的内存单元内容各为 a 和 a^b
第二步结束后,x 和 y 指向的内存单元内容各为 b 和 a^b
第三步结束后,x 和 y 指向的内存单元内容各为 b 和 a
void reverse_array(int a[], int len)
14. 假定某个实现数组元素倒置的函数 reverse_array 调用了第 13 题中给出的 xor_swap 函数:
1
2 {
3
4
5
}
6
int left, right=len-1;
for (left=0; left<=right; left++, right--)
xor_swap(&a[left], &a[right]);
当 len 为偶数时,reverse_array 函数的执行没有问题。但是,当 len 为奇数时,函数的执行结果不正
确。请问,当 len 为奇数时会出现什么问题?最后一次循环中的 left 和 right 各取什么值?最后一次
循环中调用 xor_swap 函数后的返回值是什么?对 reverse_array 函数作怎样的改动就可消除该问题?
参考答案:
当 len 为奇数时,最后一次循环执行的是将最中间的数与自己进行交换,即 left 和 right 都指向最中
间数组元素,因而在调用 xor_swap 函数过程中的每一步执行*x ^ *y 时结果都是 0,并将 0 写入到了最中
间的数组元素,从而改变了原来的数值。
可以将 for 循环中的终止条件改为“left>(n-8))<<(n-8)
(2)x & 0xFF
(3)((x^ ~0xFF) >>8 )<< 8
(3)x | 0xFF
17. 以下是一个由反汇编器生成的一段针对某个小端方式处理器的机器级代码表示文本,其中,最左边
是指令所在的存储单元地址,冒号后面是指令的机器码,最右边是指令的汇编语言表示,即汇编指
令。已知反汇编输出中的机器数都采用补码表示,请给出指令代码中划线部分表示的机器数对应的
真值。
80483d2: 81 ec b8 01 00 00 sub &0x1b8, %esp
80483d8: 8b 55 08
80483db: 83 c2 14
80483de: 8b 85 58 fe ff ff mov 0xfffffe58(%ebp), %eax
80483e4: 03 02
80483e6: 89 85 74 fe ff ff mov %eax, 0xfffffe74(%ebp)
mov 0x8(%ebp), %edx
add $0x14, %edx
add (%edx), %eax
mov 0x8(%ebp), %eax
mov 0x8(%ebp), %edx
add $0x44, %edx
add $0x20, %eax
mov %eax, (%edx)
mov 0x10(%ebp), %eax
add 0xc(%ebp), %eax
80483ec: 8b 55 08
80483ef: 83 c2 44
80483f2: 8b 85 c8 fe ff ff mov 0xfffffec8(%ebp), %eax
80483f8: 89 02
80483fa: 8b 45 10
80483fd: 03 45 0c
8048400: 89 85 ec fe ff ff mov %eax, 0xfffffeec(%ebp)
8048406: 8b 45 08
8048409: 83 c0 20
参考答案:
b8 01 00 00:机器数为 000001B8H,真值为+1 1011 1000B = 440
14:机器数为 14H,真值为+1 0100B = 20
58 fe ff ff:机器数为 FFFFFE58H,真值为-1 1010 1000B = -424
74 fe ff ff:机器数为 FFFFFE74H,真值为-1 1000 1100B = -396
44:机器数为 44H,真值为+100 0100B=68
c8 fe ff ff:机器数为 FFFFFEC8H,真值为-1 1000 1100B = -312
10:机器数为 10H,真值为+10000B=16
0c:机器数为 0CH,真值为+1100B=12
ec fe ff ff:机器数为 FFFFFEECH,真值为-1 0001 0100B = -276
20:机器数为 20H,真值为+00100000B=32
18. 假设以下 C 语言函数 compare_str_len 用来判断两个字符串的长度,当字符串 str1 的长度大于 str2 的
return strlen(str1) - strlen(str2) > 0;
int compare_str_len(char *str1, char *str2)
长度时函数返回值为 1,否则为 0。
1
2 {
3
4 }
已知 C 语言标准库函数 strlen 原型声明为“size_t strlen(const char *s);”,其中,size_t 被定义为 unsigned
int 类型。请问:函数 compare_str_len 在什么情况下返回的结果不正确?为什么?为使函数正确返回
结果应如何修改代码?
参考答案:
因为 size_t 被定义为 unsigned int 类型,因此,库函数 strlen 的返回值为无符号整数。函数
compare_str_len 中的返回值是 strlen(str1) - strlen(str2) > 0,这个关系表达式中>号左边是两个无符号
数相减,其差还是无符号整数,因而总是大于等于 0,也即在 str1 的长度小于 str2 的长度时结果也
为 1。显然,这是错误的。
只要将第 3 行语句改为以下形式即可:
3
return strlen(str1) > strlen(str2) ;
return (int) (( word <<24) >> 24);
19.考虑以下 C 语言程序代码:
int func1(unsigned word)
{
}
int func2(unsigned word)
{
}
1
2
3
4
5
6
7
8
假设在一个 32 位机器上执行这些函数,该机器使用二进制补码表示带符号整数。无符号数采用逻辑
移位,带符号整数采用算术移位。请填写表 2.14,并说明函数 func1 和 func2 的功能。
return ( (int) word <<24 ) >> 24;
w
表 2.14 题 19 用表
func1(w)
func2(w)
机器数
值
机器数
值
机器数
值
127
128
255
256
参考答案:
函数 func1 的功能是把无符号数高 24 位清零(左移 24 位再逻辑右移 24 位),当成带符号整数返回
时,结果一定是正数;函数 func2 的功能是把无符号数的高 24 位都变成和第 25 位一样,因为左移
24 位后进行算术右移,高 24 位补符号位(即第 25 位),当成带符号整数返回时,结果可能是正数
也可能是负数。
W
机器数
0000 007FH
0000 0080H
0000 00FFH
0000 0100H
值
127
128
255
256
func1(w)
func2(w)
机器数
0000 007FH
0000 0080H
0000 00FFH
0000 0000H
值
+127
+128
+255
0
机器数
0000 007FH
FFFF FF80H
FFFF FFFFH
0000 0000H
值
+127
–128
–1
0
20.填写表 2.15,注意对比无符号整数和带符号整数的乘法结果,以及截断操作前、后的结果。
x
表 2.15 题 20 用表
y
x×y(截断前)
x×y(截断后)
机器数
值
机器数
值
机器数
值
机器数
值
110
110
001
001
111
111
010
010
111
111
111
111
x
机器数
110
110
001
001
111
111
值
6
–2
1
+1
7
–1
y
机器数
010
010
111
111
111
111
值
2
+2
7
–1
7
–1
x×y(截断前)
x×y(截断后)
机器数
001 100
111 100
000 111
111 111
110 001
000 001
值
12
–4
7
–1
49
+1
机器数
100
100
111
111
001
001
值
4
–4
7
–1
1
+1
模式
无符号
带符号
无符号
带符号
无符号
带符号
参考答案:
模式
无符号数
二进制补码
无符号数
二进制补码
无符号数
二进制补码
21.以下是两段 C 语言代码,函数 arith( )是直接用 C 语言写的,而 optarith( )是对 arith( )函数以某个确定
的 M 和 N 编译生成的机器代码反编译生成的。根据 optarith( ),可以推断函数 arith( ) 中 M 和 N 的值
各是多少?
#define M
#define N
int arith (int x, int y)
{
int result = 0 ;
result = x*M + y/N;
return result;
}
}
int optarith ( int x, int y)
{
int t = x;
x << = 4;
x – = t;
if ( y < 0 ) y += 3;
y=>>2;
return x+y;
x'<-X*16
x'<-X*15
y'<-Y/4
参考答案:
可以看出 x*M 和“int t = x; x << = 4; x-=t;”三句对应,这些语句实现了 x 乘 15 的功能(左移 4 位相
当于乘以 16,然后再减 1),因此,M 等于 15;
y/N 与“if ( y < 0 ) y += 3; y>>2;”两句对应,第二句“y 右移 2 位”实现了 y 除以 4 的功能,因此 N
是 4。而第一句“if ( y < 0 ) y += 3;”主要用于对 y= –1 时进行调整,若不调整,则–1>>2= –1 而–1/4=0,
两者不等;调整后 –1+3=2,2>>2=0,两者相等。
22. 下列几种情况所能表示的数的范围是什么?
(1) 16 位无符号整数
(2) 16 位补码表示的带符号整数
(3) 下述格式的浮点数(基数为 2,移码的偏置常数为 128)
数符
1 位
阶码
8 位移码
尾数
7 位原码数值部分
参考答案:
(1)16 位无符号整数:0~65535
(2)16 位补码表示的整数:–32768 ~ +32767
(3)浮点数:负数:– (1–2–7)×2+127 ~ –2–7×2–128
正数:+2–7×2–128 ~ (1–2–7) ×2+127
23. 以 IEEE 754 单精度浮点数格式表示下列十进制数。
+1.75,+19,–1/8,258
参考答案:
+1.75 = +1.11B = 1.11B × 20, 故阶码为 0+127=01111111B, 数符为 0,尾数为 1.110…0,小数点前为隐
藏位,所以+1.7 表示为 0 01111111 110 0000 0000 0000 0000 0000,用十六进制表示为 3FE00000H。
+19 = +10011B = +1.0011B × 24,故阶码为 4+127 = 10000011B, 数符为 0,尾数为 1.00110…0,所以
+19 表示为 0 10000011 001 1000 0000 0000 0000 0000,用十六进制表示为 41980000H。
–1/8 = – 0.125 = – 0.001B = – 1.0 × 2–3,阶码为–3+127 = 01111100B,数符为 1,尾数为 1.0…0,所以–1/8
表示为 1 01111100 000 0000 0000 0000 0000 0000,用十六进制表示为 BE000000H。
258=100000010B=1.0000001B × 28, 故阶码为 8+127=10000111B, 数符为 0,尾数为 1.0000001,所以