计算机组成与汇编语言核心知识问答

1、绘制一幅冯·诺依曼架构的图。

我无法直接绘制图形,但我可以描述冯·诺依曼架构的主要组成部分,你可以根据描述来绘图:

冯·诺依曼架构主要由以下五部分组成:

  1. 运算器
  2. 控制器
  3. 存储器
  4. 输入设备
  5. 输出设备

绘图时,可将这五部分用方框表示,用箭头表示各部分之间的数据流动和控制关系。

  • 运算器 控制器 通常合称为 中央处理器(CPU)
  • 存储器 分为 内存
  • 输入设备 键盘、鼠标
  • 输出设备 显示器、打印机

2、哪个架构组件将内存与CPU连接起来?

总线(Bus)

3、高速缓存内存是如何帮助提升整体性能的?

高速缓存的作用与性能优化

如果访问一个内存位置,该值的副本会被放入高速缓存。后续对该内存位置的连续访问可从高速缓存(CPU芯片内部)获取。

  • 高速缓存命中 时,从高速缓存读取数据比从主内存读取更快。
  • 能从高速缓存满足的请求越多,系统性能通常越快。

此外,历代CPU芯片增加了高速缓存内存并改进了高速缓存映射策略,以提高整体性能。

4、在C++中,使用“int”声明的整数占用多少字节?

4字节

5、在英特尔X86 - 64架构中,每个地址可以存储多少字节?

1字节

6、给定32位十六进制数004C4B40₁₆,求:1. 最低有效字节(LSB) 2. 最高有效字节(MSB)

  1. 最低有效字节(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

  1. al :8位
  2. rcx :64位
  3. bx :16位
  4. edx :32位
  5. r11 :64位
  6. r8b :8位
  7. sil :8位
  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

  1. EF₁₆
  2. CDEF₁₆
  3. 89ABCDEF₁₆
  4. 0123456789ABCDEF₁₆

12、给出以下各项的取值范围:1. 有符号字节 2. 无符号字节 3. 有符号字 4. 无符号字 5. 有符号双字 6. 无符号双字

  1. 有符号字节:-128 到 +127
  2. 无符号字节:0 到 255
  3. 有符号字:-32768 到 +32767
  4. 无符号字:0 到 65535
  5. 有符号双字:-2147483648 到 +2147483647
  6. 无符号双字:0 到 4294967295

13、给出以下二进制数的十进制值:1. 0000101₂ 2. 0001001₂ 3. 0001101₂ 4. 0010101₂

  1. 5;2. 9;3. 13;4. 21

14、给出以下双字大小的十六进制补码值对应的十进制值。1. FFFFFFFB₁₆ 2. FFFFFFEA₁₆ 3. FFFFFFF3₁₆ 4. FFFFFFF8₁₆

十六进制补码转换为十进制值的方法

对于双字大小(32位)的十六进制补码:

  • 若最高位为1,则为负数,需先取反加1得到原码再计算十进制值;
  • 若最高位为0,则为正数,直接转换为十进制值。

转换示例

  1. FFFFFFFB₁₆
    最高位为1,是负数。
    先取反得到 00000004₁₆,再加1得到 00000005₁₆,转换为十进制是 5,
    所以该补码对应的十进制值是 -5

  2. FFFFFFEA₁₆
    最高位为1,是负数。
    先取反得到 00000015₁₆,再加1得到 00000016₁₆,转换为十进制是 22,
    所以该补码对应的十进制值是 -22

  3. FFFFFFF3₁₆
    最高位为1,是负数。
    先取反得到 0000000C₁₆,再加1得到 0000000D₁₆,转换为十进制是 13,
    所以该补码对应的十进制值是 -13

  4. 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. 制表符

  1. "A" 0x41
  2. "a" 0x61
  3. "0" 0x30
  4. "8" 0x38
  5. 制表符: 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]。

  1. mov ebx, 14 :立即数
  2. mov ecx, dword [rbx] :内存
  3. mov byte [rbx+4], 10 :立即数
  4. mov 10, rcx :非法指令
  5. mov dl, ah :寄存器
  6. mov ax, word [rsi+4] :内存
  7. mov cx, word [rbx+rsi] :内存
  8. 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

要使用调试器执行该程序并显示最终结果,可按以下步骤操作:

  1. 保存上述代码为一个 .asm 文件,例如 reverse_numbers.asm
  2. 汇编并链接该文件:
    nasm -f elf64 reverse_numbers.asm -o reverse_numbers.o ld reverse_numbers.o -o reverse_numbers
  3. 使用调试器(如 GDB)调试程序:
    gdb reverse_numbers
  4. 在 GDB 中设置断点、单步执行等操作来观察程序执行过程和最终结果。
  5. 为创建调试器输入文件,可将 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、函数调用的两个主要动作是什么?

函数调用的两个主要动作是:

  1. 链接(Linkage) :函数必须能够返回到其最初被调用的正确位置;
  2. 参数传递(Argument Transmission) :函数必须能够访问参数以进行操作或返回结果(即访问按引用传递的参数)。

63、实现链接的两条指令是什么?

实现链接的两条指令是call 和ret指令。

64、当使用值来传递参数时,这种方式被称为什么?

按值调用(call-by-value)

65、当使用地址传递参数时,这种方式被称为什么?

按引用调用(call-by-reference)

66、根据课堂上讨论的标准调用约定,大多数过程中初始压栈和最终出栈的目的是什么?

函数调用中的压栈与出栈

初始压栈(函数序言部分)的目的是保存程序状态(即特定寄存器和栈的内容),因为函数执行通常会大量使用寄存器和栈,保存状态可避免这些内容被破坏;

最终出栈(函数尾声部分)的目的是恢复之前保存的程序状态,使程序能回到调用函数之前的状态继续执行。

67、如果有六个 64 位整数参数传递给一个函数,每个参数应具体传递到哪里?

以下是调整为 Markdown 格式的文本内容:

前六个 64 位整数参数分别通过寄存器传递,依次为:

  • 第一个参数传递到 rdi
  • 第二个参数传递到 rsi
  • 第三个参数传递到 rdx
  • 第四个参数传递到 rcx
  • 第五个参数传递到 r8
  • 第六个参数传递到 r9
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值