1、绘制一幅冯·诺依曼架构的图。
我无法直接绘制图形,但我可以描述冯·诺依曼架构的主要组成部分,你可以根据描述来绘图:
冯·诺依曼架构主要由以下五部分组成:
- 运算器
- 控制器
- 存储器
- 输入设备
- 输出设备
绘图时,可将这五部分用方框表示,用箭头表示各部分之间的数据流动和控制关系。
- 运算器 和 控制器 通常合称为 中央处理器(CPU)
- 存储器 分为 内存 等
- 输入设备 如 键盘、鼠标
- 输出设备 如 显示器、打印机
2、哪个架构组件将内存与CPU连接起来?
总线(Bus)
3、高速缓存内存是如何帮助提升整体性能的?
高速缓存的作用与性能优化
如果访问一个内存位置,该值的副本会被放入高速缓存。后续对该内存位置的连续访问可从高速缓存(CPU芯片内部)获取。
- 高速缓存命中 时,从高速缓存读取数据比从主内存读取更快。
- 能从高速缓存满足的请求越多,系统性能通常越快。
此外,历代CPU芯片增加了高速缓存内存并改进了高速缓存映射策略,以提高整体性能。
4、在C++中,使用“int”声明的整数占用多少字节?
4字节
5、在英特尔X86 - 64架构中,每个地址可以存储多少字节?
1字节
6、给定32位十六进制数004C4B40₁₆,求:1. 最低有效字节(LSB) 2. 最高有效字节(MSB)
- 最低有效字节(LSB)为40;2. 最高有效字节(MSB)为00
7、给定32位十六进制数004C4B40₁₆,展示其小端字节序的内存布局,显示内存中的每个字节。
| 地址(十六进制) | 值 |
|---|---|
| 0100100C | 00 |
| 0100100B | 4C |
| 0100100A | 4B |
| 01001009 | 40 |
8、以下每个寄存器分别代表多少位:1. al 2. rcx 3. bx 4. edx 5. r11 6. r8b 7. sil 8. r14w
-
al:8位 -
rcx:64位 -
bx:16位 -
edx:32位 -
r11:64位 -
r8b:8位 -
sil:8位 -
r14w:16位
9、哪个寄存器指向栈的当前顶部?
rsp寄存器指向栈的当前顶部。
10、如果al被设置为05₁₆,ax被设置为0007₁₆,eax被设置为00000020₁₆,rax被设置为0000000000000000₁₆,请给出完整rax寄存器的最终完整内容。
0000000000000000₁₆
11、如果rax寄存器被设置为十进制的81,985,529,216,486,895(十六进制的123456789ABCDEF),那么以下寄存器的十六进制内容分别是什么?1. al 2. ax 3. eax 4. rax
-
EF₁₆ -
CDEF₁₆ -
89ABCDEF₁₆ -
0123456789ABCDEF₁₆
12、给出以下各项的取值范围:1. 有符号字节 2. 无符号字节 3. 有符号字 4. 无符号字 5. 有符号双字 6. 无符号双字
- 有符号字节:-128 到 +127
- 无符号字节:0 到 255
- 有符号字:-32768 到 +32767
- 无符号字:0 到 65535
- 有符号双字:-2147483648 到 +2147483647
- 无符号双字:0 到 4294967295
13、给出以下二进制数的十进制值:1. 0000101₂ 2. 0001001₂ 3. 0001101₂ 4. 0010101₂
- 5;2. 9;3. 13;4. 21
14、给出以下双字大小的十六进制补码值对应的十进制值。1. FFFFFFFB₁₆ 2. FFFFFFEA₁₆ 3. FFFFFFF3₁₆ 4. FFFFFFF8₁₆
十六进制补码转换为十进制值的方法
对于双字大小(32位)的十六进制补码:
- 若最高位为1,则为负数,需先取反加1得到原码再计算十进制值;
- 若最高位为0,则为正数,直接转换为十进制值。
转换示例
-
FFFFFFFB₁₆ :
最高位为1,是负数。
先取反得到 00000004₁₆,再加1得到 00000005₁₆,转换为十进制是 5,
所以该补码对应的十进制值是 -5 。 -
FFFFFFEA₁₆ :
最高位为1,是负数。
先取反得到 00000015₁₆,再加1得到 00000016₁₆,转换为十进制是 22,
所以该补码对应的十进制值是 -22 。 -
FFFFFFF3₁₆ :
最高位为1,是负数。
先取反得到 0000000C₁₆,再加1得到 0000000D₁₆,转换为十进制是 13,
所以该补码对应的十进制值是 -13 。 -
FFFFFFF8₁₆ :
最高位为1,是负数。
先取反得到 00000007₁₆,再加1得到 00000008₁₆,转换为十进制是 8,
所以该补码对应的十进制值是 -8 。
结论
综上,答案依次为 -5、-22、-13、-8 。
15、以下哪个十进制值在二进制中有精确表示?1. 0.1 2. 0.2 3. 0.3 4. 0.4 5. 0.5
5
16、以下字符的十六进制 ASCII 码分别是什么:1. “A” 2. “a” 3. “0” 4. “8” 5. 制表符
-
"A":0x41 -
"a":0x61 -
"0":0x30 -
"8":0x38 -
制表符:
0x09
17、在汇编语言程序中,注释是如何标记的?
在汇编语言程序中,分号(
;
)用于标记程序注释。分号可置于任何位置,包括指令之后,分号后的任何字符都会被汇编器忽略。
18、已初始化数据声明所在的节的名称是什么?
数据段(data section)
19、未初始化数据声明所在的节的名称是什么?
BSS节
20、代码放置的段的名称是什么?
.text
21、对于以下变量,给出每个变量具有给定值的数据声明:1. 字节大小的变量bNum设置为1010;2. 字大小的变量wNum设置为10291;3. 双字大小的变量dwNum设置为2126010;4. 四字大小的变量qwNum设置为10000000000。
bNum db 1010
wNum dw 10291
dwNum dd 2126010
qwNum dq 10000000000
22、以下各项的未初始化数据声明分别是什么:1. 一个名为 bArr 的、包含 100 个元素的字节数组;2. 一个名为 wArr 的、包含 3000 个元素的字数组;3. 一个名为 dwArr 的、包含 200 个元素的双字数组;4. 一个名为 qArr 的、包含 5000 个元素的四字数组。
1. bArr resb 100;
2. wArr resw 3000;
3. dwArr resd 200;
4. qArr resq 5000
23、在文本段中,标志程序开始所需的声明有哪些?
需要包含以下声明:global _start _start:
24、汇编器第一遍扫描会执行哪些操作?
汇编器第一遍扫描执行的基本操作
汇编器第一遍扫描执行的基本操作包括:
- 创建符号表
- 展开宏
- 计算常量表达式
此外,还会为程序中的所有语句分配地址,并处理一些汇编器指令。
25、汇编器第二遍扫描执行哪些操作?
汇编器第二遍扫描执行的基本操作
汇编器在第二遍扫描期间执行以下基本操作:
- 最终生成代码
- 将程序员提供的汇编语言指令转换为CPU可执行的机器语言指令。
-
在代码生成过程中,会使用符号表来检查程序中使用的符号并获取相应的地址。
-
创建列表文件(如果有请求)
- 列表文件可用于调试目的。
-
如果用户请求生成列表文件,则在第二遍扫描期间创建。
-
创建目标文件
- 如果在处理过程中没有发现错误,则在第二遍扫描期间创建最终的目标文件。
26、链接器执行哪些操作?
链接器的操作包括:
- 将较小的解决方案组合成一个可执行单元
- 若使用了用户或系统库例程,会包含相应的例程
- 将目标文件和库例程组合成单个可执行模块
- 把机器语言代码从每个目标文件复制到单个可执行文件中
在组合目标文件时:
- 必要时调整可重定位地址
- 满足外部引用
- 将外部引用的最终位置放入代码中
27、加载器会执行哪些操作?
- 尝试打开可执行文件(验证其存在性和权限)
- 读取头信息
- 请求操作系统创建新进程
-
若成功:
- 读取可执行文件的其余部分并加载到内存(由操作系统指定位置)
- 在加载完成时通知操作系统
- 注意:加载器不运行进程
28、请给出一个常量表达式的示例。
假设常量 BUFF 已定义,指令“mov rax, BUFF+5”包含一个常量表达式。
29、为确保程序易于调试,在汇编和链接步骤中需要什么选项?
-g 限定符必须包含在汇编和链接步骤中。
30、continue命令具体有什么作用?
在初始运行命令之后,使用
continue
命令(通过点击
Cont
菜单窗口或在
(gdb)
提示符下输入
cont
)可继续执行程序到下一个断点;
continue <n>
|
c <n>
可继续执行程序到下一个断点,跳过
n - 1
次断点跨越,可用于快速到达循环的第
n
次迭代。
31、寄存器窗口如何显示?
寄存器窗口默认不显示,但可通过选择顶部菜单栏中的 “Status → Registers” 来查看。显示时,寄存器窗口将按寄存器名称(左列)显示寄存器内容,同时以十六进制(中间列)和无符号十进制(右列)显示。
32、寄存器窗口有三列。第一列显示寄存器。另外两列显示什么?
中间列以十六进制显示寄存器内容,右列以无符号十进制显示寄存器内容;对于某些特殊用途寄存器(如
rbp
和
rsp
),两列都以十六进制显示。第三列一般显示十进制四字表示,但对于特殊用途寄存器(
rbp
和
rsp
)除外,有符号四字十进制表示并非总是有意义。
33、调试器启动后,用户如何退出?
-
可以在输入文件中使用
'quit'命令退出调试器; -
若输入文件中移除了
'quit'命令,退出输入文件时,调试器可能会请求用户确认是否退出(回答yes或no); -
另外,也可通过命令行输入
'gdb <gdbIn.txt prog'执行输入文件中的命令,创建输出文件并退出程序。
34、描述设置断点的多种方法。
可以通过在底部窗口(
(gdb)
提示符处)输入命令
break <label/addr>
或其缩写
b <label/addr>
来设置断点,其中
<label/addr>
表示标签或地址。
35、从文件中读取调试器命令的调试器命令是什么?
source
36、当 DDD 显示一个绿色箭头指向一条指令时,这意味着什么?
绿色箭头指向的是下一条要执行的指令,即绿色箭头所指的语句尚未执行。
37、显示当前栈顶值的调试器命令是什么?
x/ug $rsp
38、显示当前栈顶的五个值的调试器命令是什么?
x/5ug $rsp
39、输入一个示例程序,对该程序进行汇编和链接操作。执行调试器,在标签“last”处设置断点并执行程序到该断点处。交互式地验证所执行的计算是否得出了正确的值,这需要根据变量大小输入相应的调试器检查内存命令。
下面是给定的【文本内容】:需按要求完成以下操作:
1. 输入示例程序;
2. 对程序进行汇编和链接操作;
3. 执行调试器;
4. 在标签last处设断点并执行程序;
5. 根据变量大小用调试器检查内存命令验证计算结果。
40、创建一个汇编和链接脚本文件,使用该脚本对程序进行汇编和链接,确保脚本能正确完成汇编和链接操作。
可以创建如下的简单 bash 汇编/链接脚本:
#!/bin/bash
# 简单的汇编/链接脚本。
if [ -z $1 ]; then
echo "Usage: ./asm64 <asmMainFile> (no extension)"
exit
fi
将上述脚本内容保存为一个文件,例如
asm64
,并赋予执行权限:
chmod +x asm64
。
然后在命令行中运行
./asm64 <asmMainFile>
(
<asmMainFile>
为无扩展名的汇编主文件名)来进行汇编和链接操作。
41、解释以下两条指令的区别:1. mov rdx, qword [qVar1] 2. mov rdx, qVar1
下面是给定的【文本内容】:
指令1
mov rdx, qword [qVar1]
是将内存地址
qVar1
处存储的8字节(64位)数据移动到寄存器
rdx
中;
指令2
mov rdx, qVar1
是将变量
qVar1
的地址本身移动到寄存器
rdx
中。
42、以下列出的每条指令的源操作数的寻址模式是什么?请用寄存器、立即数、内存或非法指令作答。注意,mov <目的操作数>, <源操作数> 。指令如下:mov ebx, 14;mov ecx, dword [rbx];mov byte [rbx+4], 10;mov 10, rcx;mov dl, ah;mov ax, word [rsi+4];mov cx, word [rbx+rsi];mov ax, byte [rbx]。
-
mov ebx, 14:立即数 -
mov ecx, dword [rbx]:内存 -
mov byte [rbx+4], 10:立即数 -
mov 10, rcx:非法指令 -
mov dl, ah:寄存器 -
mov ax, word [rsi+4]:内存 -
mov cx, word [rbx+rsi]:内存 -
mov ax, byte [rbx]:内存
43、给定以下变量声明和代码片段:ans1 dd 7 mov rax, 3 mov rbx, ans1 add eax, dword [rbx] 执行后eax寄存器中的值是什么?以十六进制、完整寄存器大小显示答案。
0x0000000A
44、给定以下变量声明和代码片段:list1 dd 2, 3, 4, 5, 6, 7 mov rbx, list1 add rbx, 4 mov eax, dword [rbx] mov edx, dword [list1] 执行后eax和edx寄存器中的值是什么?以十六进制、完整寄存器大小显示答案。
eax寄存器的值为0x00000003,edx寄存器的值为0x00000002
45、实现示例程序来计算一个数字列表的总和。使用调试器执行该程序并显示最终结果。创建一个调试器输入文件来展示结果。
- 按要求实现计算数字列表总和的示例程序
- 利用调试器运行该程序
- 显示最终计算得到的总和结果
- 创建调试器输入文件记录该结果
46、创建一个程序来对一个数字列表进行排序。使用以下冒泡排序算法:从列表长度减 1 开始到 0 进行外层循环,每次外层循环开始时将交换标志设为 false,在内层循环中从 0 到当前外层循环变量减 1 进行遍历,如果当前元素大于后一个元素,则交换这两个元素,并将交换标志设为 true。若某一次外层循环中交换标志一直为 false,则提前结束排序。使用调试器执行该程序并显示最终结果,同时创建一个调试器输入文件来展示结果。
冒泡排序程序与调试步骤
首先按照给定的冒泡排序算法编写程序对数字列表排序,然后使用调试器运行该程序以获取最终排序好的列表,最后创建一个调试器输入文件来展示排序结果。
对于具体代码实现,以 Python 为例:
lst = [5, 3, 8, 4, 2]
len_lst = len(lst)
for i in range(len_lst - 1, 0, -1):
swapped = False
for j in range(0, i):
if lst[j] > lst[j + 1]:
tmp = lst[j]
lst[j] = lst[j + 1]
lst[j + 1] = tmp
swapped = True
if not swapped:
break
print('排序后的列表:', lst)
对于调试和创建调试器输入文件,不同的开发环境操作不同。例如在 PyCharm 中,可以设置断点进行调试,将排序结果输出到文件作为调试器输入文件展示结果。
47、哪个寄存器指向栈顶?
rsp寄存器用于指向当前栈顶。
48、执行 push rax 指令会产生哪两个结果?
首先,相应地调整rsp(rsp - 8),然后将操作数复制到[rsp]。
49、pop rax 指令从栈中移除多少字节的数据?
8 字节
50、给定以下代码片段:mov r10, 1 mov r11, 2 mov r12, 3 push r10 push r11 push r12 pop r10 pop r11 pop r12 执行后 r10、r11 和 r12 寄存器中的值是什么?以十六进制、完整寄存器大小显示答案。
r10: 0x0000000000000001,r11: 0x0000000000000002,r12: 0x0000000000000003
51、给定以下变量声明和代码片段:lst dq 1, 3, 5, 7, 9 mov rsi, 0 mov rcx, 5 lp1: push qword [lst+rsi 8] inc rsi loop lp1 mov rsi, 0 mov rcx, 5 lp2: pop qword [lst+rsi 8] inc rsi loop lp2 mov rbx, qword [lst] 解释代码执行后的结果是什么?
代码首先将列表
lst
中的元素依次压入栈中,然后再从栈中弹出元素依次存回
lst
中,实现了列表元素的逆序。
最后将逆序后
lst
的第一个元素(即原来的最后一个元素
9
)存入
rbx
寄存器。所以执行后
rbx
寄存器的值为
9
。
52、实现一个示例程序来反转一个数字列表。使用调试器执行该程序并显示最终结果。创建一个调试器输入文件来展示结果。
以下是用于反转数字列表的示例程序代码:
; Simple example demonstrating basic stack operations.
; Reverse a list of numbers - in place.
; Method: Put each number on stack, then pop each number
; back off, and then put back into memory.
; *****************************************************
; Data declarations section
.data
; -----
; Define constants
EXIT_SUCCESS equ 0 ; successful operation
SYS_exit equ 60 ; call code for terminate
; -----
; Define Data.
numbers dq 121, 122, 123, 124, 125
len dq 5
; ****************************************************
section .text
global _start
_start:
; Loop to put numbers on stack.
mov rcx, qword [len]
mov rbx, numbers
mov r12, 0
mov rax, 0
pushLoop:
push qword [rbx + r12*8]
inc r12
loop pushLoop
; Loop to pop numbers from stack and put back into array
mov rcx, qword [len]
mov r12, 0
popLoop:
pop qword [rbx + r12*8]
inc r12
loop popLoop
; Exit the program
mov rax, SYS_exit
mov rdi, EXIT_SUCCESS
syscall
要使用调试器执行该程序并显示最终结果,可按以下步骤操作:
-
保存上述代码为一个
.asm文件,例如reverse_numbers.asm。 -
汇编并链接该文件:
nasm -f elf64 reverse_numbers.asm -o reverse_numbers.o ld reverse_numbers.o -o reverse_numbers -
使用调试器(如 GDB)调试程序:
gdb reverse_numbers - 在 GDB 中设置断点、单步执行等操作来观察程序执行过程和最终结果。
-
为创建调试器输入文件,可将 GDB 中的命令保存到一个文件中,例如
gdb_input.txt,文件内容可包含设置断点、运行程序等命令,然后在 GDB 中使用source gdb_input.txt执行这些命令。
53、如果单操作数乘法指令使用立即数操作数,会发生哪种类型的错误(如果有的话)?请用汇编时(assemble - time)或运行时(run - time)作答。
汇编时(assemble - time)
54、如果汇编语言指令拼写错误(例如,用“mv”代替“mov”),何时会发现错误?请用汇编时(assemble - time)或运行时(run - time)作答。
汇编时
55、如果一个标签被引用但未被定义,该错误将在何时被发现?请回答汇编时或运行时。
汇编时
56、如果一个程序对数组中的值进行一系列除法运算时出现除以 0 的情况,这个错误会在什么时候被发现?请回答汇编时(assemble-time)或运行时(run-time)。
运行时
57、在汇编语言源文件中,宏定义放在哪里?
宏定义应放在源文件的数据和代码段之前。
58、当宏被调用时,代码会在代码段中放置多少次?
每次宏被调用时放置一次。
59、解释为什么在宏中,标签通常以两个百分号(%%)开头。
%%会确保每次使用宏时生成一个唯一的标签名,保证多次调用同一宏时每次使用不同的标签。
60、解释如果标签中不包含 %% 可能会发生什么?
如果标签中省略了 %%,标签将原样复制,因此看起来会重复。
61、宏参数替换在什么时候发生?
汇编时
62、函数调用的两个主要动作是什么?
函数调用的两个主要动作是:
- 链接(Linkage) :函数必须能够返回到其最初被调用的正确位置;
- 参数传递(Argument Transmission) :函数必须能够访问参数以进行操作或返回结果(即访问按引用传递的参数)。
63、实现链接的两条指令是什么?
实现链接的两条指令是call 和ret指令。
64、当使用值来传递参数时,这种方式被称为什么?
按值调用(call-by-value)
65、当使用地址传递参数时,这种方式被称为什么?
按引用调用(call-by-reference)
66、根据课堂上讨论的标准调用约定,大多数过程中初始压栈和最终出栈的目的是什么?
函数调用中的压栈与出栈
初始压栈(函数序言部分)的目的是保存程序状态(即特定寄存器和栈的内容),因为函数执行通常会大量使用寄存器和栈,保存状态可避免这些内容被破坏;
最终出栈(函数尾声部分)的目的是恢复之前保存的程序状态,使程序能回到调用函数之前的状态继续执行。
67、如果有六个 64 位整数参数传递给一个函数,每个参数应具体传递到哪里?
以下是调整为 Markdown 格式的文本内容:
前六个 64 位整数参数分别通过寄存器传递,依次为:
-
第一个参数传递到
rdi -
第二个参数传递到
rsi -
第三个参数传递到
rdx -
第四个参数传递到
rcx -
第五个参数传递到
r8 -
第六个参数传递到
r9
426

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



