P33页,第3题
题目
在本章所设计的原型系统中,实现两个正整数相乘(假设乘积不超过127),并在虚拟程序中运行。
答案
汇编代码如下:
# 两个大于1的正数相乘
1 in R1 # 乘数a
2 movb R0,R1 # 乘数a存放到内存0000 0000
3 in R1 # 被乘数b
4 movi 1
5 movb R0,R1 # 被乘数b存放在内存0000 0001
# 结果存放在内存 0000 0010
# 开始循环
6 movi 1 # R0中的值为1
7 movc R1,R0 # 从内存中取出值b
8 movi 1 # 设置R0中的值为1
9 sub R1,R0 # R1即b值减1,此时设置G值
10 movi 1
11 movb R0,R1 # b值需要保存回去
12 movi 0 # R0中设置为0,即内存地址0
13 movc R2,R0 # 取出a值
14 movi 2 # R0中设置为2,即内存地址0000 0010
15 movc R1,R0 # 取出结果
16 add R1,R2 # 做加法
17 movb R0,R1 # 将结果存回去
18 movd # 保存当前的PC值到R3
19 movi -12 # R0的值设置为-12
20 add R3,R0 # R3的值加-12
21 jg # 如果第12行的减法设置G为1,就跳转
# 循环结束
22 movi 2 # R0中设置为2,即内存地址0000 0010
23 movc R1,R0 # 取出结果
24 out R1 # 打印结果
25 halt
在VSPM中运行情况如下:


P47页,第3题
题目
当我们调用汇编器的时候,下面代码中的每一行都会产生一个错误信息,请在机器上运行,阅读错误提示信息,并解释每一行是哪里出了错,如何修改。
movb $0xF,(%ebx)
movw %eax,(%esp)
movl (%eax),4(%esp)
movb %al,%sl
movl %eax,$0xFFFFFFFF
movw %eax,%bx
movb %si, 8(%esp)
答案
对于第一句movb $0xF,(ebx),汇编后无错误。

对于第二句movw %eax,(%esp),汇编后报错如下:

错误原因是%eax是32位寄存器,而movw是16位的数据传送指令,二者不匹配。应将movw改为movl。
对于第三句movl (%eax),4(%esp),汇编后报错如下:

错误原因是mov指令不允许源操作数和目标操作数都是内存地址。应将(%eax)改为%eax。
对于第四句movb %al,%sl,汇编后报错如下:

错误原因是不存在%sl寄存器。应将%sl改为%bl。
对于第五句movl %eax,$0xFFFFFFFF,汇编后报错如下:

错误原因是$0xFFFFFFFF是立即数,而mov指令的目标操作数不能是立即数。应将%eax与$0xFFFFFFFF位置互换。
对于第六句movw %eax,%bx,汇编后报错如下:

错误原因是%eax是32位寄存器,而movw是16位的数据传送指令,二者不匹配。应将%eax改为%ax。
对于第七句movb %si, 8(%esp),汇编后报错如下:

错误原因是%si是16位寄存器,而movb是8位的数据传送指令,二者不匹配。应将movb改为movw。
P48页,第6题
题目
假设下面的值存放在指定的存储器地址和寄存器中:
|
地址 |
值 |
|
0x100 |
0xFF |
|
0x104 |
0xAB |
|
0x108 |
0x13 |
|
0x10C |
0x11 |
|
寄存器 |
值 |
|
%eax |
0x100 |
|
%ecx |
0x1 |
|
%edx |
0x3 |
填写下表,给出下面指令的效果,说明将被更新的寄存器或存储器位置,以及得到的值。
|
指令 |
目的 |
值 |
|
addl %ecx,(%eax) | ||
|
subl %edx,4(%eax) | ||
|
imull $16,(%eax,%edx,4) | ||
|
incl 8(%eax) | ||
|
decl %ecx | ||
|
subl %edx,%eax |
答案
|
指令 |
目的 |
值 |
|
addl %ecx,(%eax) |
内存地址0x100 |
0x100 |
|
subl %edx,4(%eax) |
内存地址0x104 |
0xA8 |
|
imull $16,(%eax,%edx,4) |
内存地址0x10C |
0x110 |
|
incl 8(%eax) |
内存地址0x108 |
0x14 |
|
decl %ecx |
寄存器%ecx |
0x0 |
|
subl %edx,%eax |
寄存器%eax |
0xFD |
P48页,第7题
题目
我们经常可以看见以下形式的汇编代码行:
xorl %eax,%eax
但是在产生这段汇编代码的C语言代码块中,并没有出现EXCLUSIVE-OR操作。
(1)解释这条指令实现了什么操作。
(2)更直接表达这个操作的汇编代码是什么?
(3)比较同一个操作的两种不同实现的编码字节长度。
答案
(1)将%eax寄存器中的值和自己做异或,结果写回到%eax寄存器中。由于任何数与自身异或的结果为 0,故该指令的实际作用是将寄存器%eax的值清零。
(2)
movl $0,%eax
(3)xorl %eax, %eax的编码:机器码为31 C0,长度为2字节。短小高效,适合频繁清零的场景(如循环或函数初始化);
movl $0, %eax的编码:机器码为B8 00 00 00 00,长度为5字节。需要编码一个 32位立即数$0,导致指令较长。
193

被折叠的 条评论
为什么被折叠?



