指令格式和寻址方式
指令格式是计算机组成原理中的重点考察内容,需熟练掌握,熟练张常常在大题中与 CPU 的知识交叉考察。
计算机程序的执行过程
计算机程序的生命周期通常包括编译(compile)、汇编(assemble)、链接(linking)和执行(execute)等阶段。这些阶段是构建和运行程序的重要步骤。以下是这些阶段的简要说明:
- 编译(Compile):
- 编译是将高级编程语言(如 C、C++、Java 等)源代码翻译为目标机器的汇编语言或机器代码的过程。
- 编译器(如 GCC、Clang、Visual C++)负责将源代码转化为目标代码,并生成一个中间表示,如汇编语言或机器码。
- 这个阶段的目标是检查源代码中的语法错误和逻辑错误,并生成可执行程序的中间文件。
- 汇编(Assemble):
- 汇编是将汇编语言源代码(通常是由编译器生成的中间表示)转化为机器码的过程。
- 汇编器(如 NASM、MASM)负责将汇编语言代码转化为可执行程序所需的机器码。
- 这个阶段的目标是将源代码翻译为可执行代码,并生成一个目标文件。
- 链接(Linking):
- 链接是将程序的不同部分(如多个源代码文件、库文件等)组合在一起,以创建最终的可执行程序的过程。
- 链接器(如 ld、linker)负责解析程序中的符号引用,将它们与符号定义(如函数、变量)关联起来,以创建一个完整的可执行文件。
- 这个阶段的目标是解决符号引用,创建可执行程序,并将各种模块整合到一个单独的可执行文件中。
- 执行(Execute):
- 执行是将最终生成的可执行程序加载到内存中,并由计算机的中央处理单元(CPU)执行的过程。
- 操作系统负责加载可执行程序,并将控制权转交给程序的起始点。
- 可执行程序的指令将由 CPU 执行,从而实现程序的功能。
指令的格式
指令中主要包含两个部分:操作码(opcode)以及 地址(address)。
这里地址是一个通用含义,指的是操作的对象,可以是一个内存地址,也可以是 CPU 中的一个寄存器。
指令类型
根据指令中的地址个数,可以将指令划分为以下类型。
指令格式 | 含义 |
---|---|
零地址指令 | $OP$ |
一地址指令 | $OP(A_1) \rightarrow A_1$ |
二地址指令 | $(A_1)OP(A_2) \rightarrow A_1$ |
三地址指令 | $(A_1)OP(A_2) \rightarrow A_3$ |
指令根据其操作码(opcode)的不同可以分为以下类别:
- 数据传输指令
MOV
:将数据从一个位置传输到另一个位置,可以是寄存器到寄存器、内存到寄存器、寄存器到内存等。PUSH
:将数据(通常是寄存器中的值)推入堆栈。POP
:从堆栈中弹出数据并存储到寄存器中。
- 算术和逻辑运算指令
ADD
、SUB
、MUL
、DIV
:执行算术运算,如加法、减法、乘法和除法。AND
、OR
、XOR
、NOT
:执行逻辑运算,如按位与、按位或、按位异或和按位取反。INC
、DEC
:递增和递减操作数的值。CMP
:用于比较两个值,并根据结果设置标志寄存器的状态。
- 控制转移指令
JMP
:用于无条件跳转到指定的目标地址。Jxx
:条件跳转指令,根据特定的条件(如零标志、进位标志等)来决定是否跳转。CALL
:调用子程序或函数。RET
:从子程序返回。
- 输入/输出指令
IN
:从外部设备或端口读取数据。OUT
:向外部设备或端口发送数据。
- 字符串操作指令(String Instructions):
MOVS
、LODS
、STOS
、CMPS
:用于在内存中执行字符串操作,如移动、加载、存储、比较。
- 陷阱指令(Trap Instructions):
INT
:用于引发中断,通常用于与操作系统进行通信。
- 协处理器指令(Coprocessor Instructions):
CLI
、STI
:用于清除和设置 CPU 的中断标志,通常只能在内核模式下执行。
寻址方式
计算机中的寻址方式(Addressing Modes)是指在指令中如何指定操作数的位置或地址。
寻址方式 | 描述 | 示例 |
---|---|---|
立即寻址 | 操作数直接包含在指令中。 | MOV R1, #5 (将5加载到R1寄存器) |
寄存器寻址 | 操作数在寄存器中。 | ADD R1, R2 (R2加到R1中) |
直接寻址 | 操作数的内存地址直接包含在指令中。 | MOV R1, [1000] (从内存地址1000取数据) |
间接寻址 | 操作数的地址由指令指定的内存地址提供,指令通过这个地址访问操作数。 | MOV R1, [R2] (R2中存储的是操作数的地址) |
寄存器间接寻址 | 操作数的地址存储在寄存器中,指令通过寄存器访问内存中的数据。 | MOV R1, [R2] (R2寄存器中是内存地址) |
基址寻址 | 使用基址寄存器和偏移量计算操作数的实际地址。 | MOV R1, [R2 + 4] (基址R2加偏移4) |
变址寻址 | 通过基址寄存器和索引寄存器的和来确定操作数地址,常用于数组操作。 | MOV R1, [R2 + R3] (R2与R3相加) |
相对寻址 | 操作数地址通过程序计数器(PC)当前值加上指令中的偏移量计算,常用于跳转指令。 | JMP LABEL (跳转到相对地址) |
堆栈寻址 | 通过堆栈顶指针(SP)来访问操作数,常用于函数调用和返回。 | PUSH R1 (将R1压入堆栈) |