第二章 x86处理器架构
中央处理单元(CPU)处理算术和逻辑运算。它包含了有限数量的存储位置,即寄存器,一个高频时钟用于同步其操作,一个控制单元和一个算术逻辑单元。内存存储单元在计算机程序运行时,保存指令和数据。总线是一组并行线路,在计算机不同部件之间传输数据。
一条机器指令的执行可以分为一系列独立的操作,称为指令执行周期。3个主要操作分别为取值、译码和执行。指令周期中的每一步都至少要花费一个系统时钟单位,即时钟周期。加载和执行过程描述了程序如何被操作系统定位,加载入内存,再由操作系统执行。
x86处理器系列有三种基本操作模式:保护模式、实地址模式和系统管理模式。此外,还有一个虚拟8086模式是保护模式的一个特例。Intel 64处理器系列有两种基本操作模式:
兼容模式和64位模式。在兼容模式下处理器可以运行16位和32位应用程序。
寄存器位CPU内的存储位置进行命名,其访问速度比常规内存要快很多。以下是对寄存器的简要说明:
l 通用寄存器主要用于算术运算、数据传输和逻辑操作。
l 段寄存器存放预先分配的内存区域的基址,这些内存区域就是段。
l 指令指针寄存器存放的是下一条要执行指令的地址。
l 标志寄存器包含的独立二进制位于控制CPU的操作,并反映ALU操作的结果。
x86有一个浮点单元(FPU)专门用于高速浮点指令的执行。
微型计算机的心脏是它的主板,主板上有CPU、支持处理器、内存、输入输出接口、电源接口和扩展插槽。PCI(外部设备互联)总线为Pentium处理器提供了方便的升级途径。大多数主板集成了若干微处理器和控制器,称为芯片组。芯片组在很大程度上决定了计算机的性能。
PC中使用的集中基本存储器:ROM、EPROM、动态RAM(DRAM)、静态RAM(SRAM)、视频RAM(VRAM)和CMOS RAM。
与虚拟机概念相似,输入输出是通过不同层次的访问来实现。库函数在最高层,操作系统是次高层。BIOS(基本输入输出系统)是一组函数,能直接与硬件设备通信。程序也可以直接访问输入输出设备。
第三章 汇编语言基础
整型常量表达式是算术表达式,包括了整数常量、符号常量和算术运算符。优先级是指当表达式有两个或更多运算符时,运算符的隐含顺序。
字符常量是用引号括起来的单个字符。汇编器把字符转换为一个字节,其中包含的是该字符的二进制ASCII码。字符串常量是用引号括起来的字符序列,可以选择用空字节标记结束。
汇编语言有一组保留字,它们含义特殊且只能用于正确的上下文中。标识符是程序员选择的名称,用于标识变量、符号常量、子程序和代码标号。不能用保留字作标识符。
伪指令是嵌在源代码中的命令,由汇编器进行转换。指令是源代码语句,由处理器在运行时执行。指令助记符是短关键字,用于标识指令执行的操作。标号是一种标识符,用作指令或数据的位置标记。
操作数是传递给指令的数据。一条汇编指令有0~3个操作数,每一个都可以是寄存器、内存操作数、整数表达式或输入/输出端口号。
程序包括了逻辑段,名称分别为代码段、数据段和堆栈段。代码段包含了可执行指令;堆栈段包含了子程序参数、局部变量和返回地址;数据段包含了变量。
源文件包含了汇编语言语句。列表文件包含了程序源代码的副本,再加上行号、偏移地址、翻译的机器代码和符号表,适合打印。源文件用文本编辑器创建。汇编器是一种程序,它读取源文件,并生成目标文件和列表文件。链接器也是一种程序,它读取一个或多个目标文件,并生成可执行文件。后者由操作系统加载器来执行。
MASM识别内部数据类型,每一种类型都描述了一组数值,这些数值能分配给指定类型的变量和表达式:
l BYTE和SBYTE定义8位变量。
l WORD和SWORD定义16位变量。
l DWORD和SDWORD定义32位变量。
l QWORD和TBYTE分别定义8字节和10字节变量。
l REAL4、REAL8和REAL10分别定义4字节、8字节和10字节实数变量。
数据定义语句为变量预留内存空间,并可以选择性地给变量分配一个名称。如果一个数据定义有多个初始值,那么它的标号仅指向第一个初始值的偏移量。创建字符串数据定义时,要用引号把字符序列括起来。DUP运算符用常量表达式作为计数器,生成重复的存储分配。当前地址计数器运算符($)用于地址计算表达式。
x86处理器用小端顺序在内存中存取数据:变量的最低有效字节存储在其起始(最低)地址中。
符号变量(或符号定义)把标识符与一个整数或文本表达式连接起来。有3个伪指令能够定义符号常量:
l 等号伪指令(=)连接符号名称与整数常量表达式。
l EQU和TESTEQU伪指令连接符号名称与整数常量表达式或一些任意的文本。
第四章 数据传送、寻址和算术运算
MOV,数据传送指令,将源操作数复制到目的操作数。MOVZX指令讲一个较小的操作数扩展为较大的操作数。MOVSX指令将一个较小的操作数符号扩展为较大的操作数。XCHG指令交换两个操作数的内容,指令中至少有一个操作数是寄存器。
操作数类型 本章中出现了下列操作数类型:
l 直接操作数是变量的名字,表示该变量的地址。
l 直接—偏移量操作数是在变量名上加位移,生成新的偏移量。可以用它来访问内存数据。
l 间接操作数是寄存器,其中存放了数据地址。通过在寄存器名外面加方括号(如[esi]),程序就能解析该地址,并检索内存数据。
l 变址操作数将间接操作数与常数组合在一起。常数与寄存器值相加,并解析结果偏移量。如,[array+esi]和[esi]都是变址操作数。
下面列出了重要的算术运算指令:
l INC指令实现操作数加1。
l DEC指令实现操作数减1。
l ADD指令实现源操作数与目的操作数相加。
l SUB指令实现目的操作数减去源操作数。
l NEG指令实现操作数符号翻转。
当把简单算术运算表达式转换为汇编语言时,利用标准运算符优先级原则来选择首先实现哪个表达式。
状态标志位 下面列出了受算术运算操作影响的CPU状态标志:
l 算术运算操作结果为负时,符号标志位置1。
l 与目标操作数相比,无符号算术运算操作结果太大时,进位标志位置1。
l 执行算术或布尔指令后,奇偶标志位能立即反映出目标操作数最低有效字节中1的个数是奇数还是偶数。
l 目标操作数的位3有进位或借位时,辅助进位标志位置1。
l 算术操作结果为0时,零标志位置1。
l 有符号算术运算操作结果超过目标操作数范围时,溢出标志位置1。
运算符 下面列出了汇编语言中常用的运算符:
l OFFSET运算符返回的是变量与其所在段首地址的距离(按字节计)。
l PTR运算符重新定义变量的大小。
l TYPE运算符返回的是单个变量或数组中单个元素的大小(按字节计)。
l LENGTHOF运算符返回的是,数组元素的个数。
l SIZEOF运算符返回的是,数组初始化的字节数。
l TYPEDEF运算符创建用户定义类型。
循环 JMP(跳转)指令无条件分支到另一个位置。LOOP(按ECX计数器内容进行循环)指令用于计数型循环。32位模式下,LOOP用ECX作计数器;64位模式下,用RCX作计数器。两种模式下,LOOPD用ECX作计数器;LOOPW用CX作计数器。
MOV指令的操作在32位模式和64位模式下几乎相同。但是,向64位寄存器送常数和内存操作数则有点棘手。只要有可能,在64位模式下尽量使用64位操作数,间接操作数和变址操作数也总是使用64位寄存器。
第五章 过程
这一章介绍了本书的链接库,使读者在汇编语言应用程序中更便于进行输入输出的处理。
表5-1列出了Irvine32链接库中的绝大多数过程。本书(www.asmirvine.com)上可以获取所有过程最新更新的列表。
5.4.4节中的库测试程序演示了若干Irvine32库的输入输出函数。它生成并显示了一组随机数、寄存器的内容和内存区域的内容。它还显示了各种格式的整数并演示了字符串的输入输出。
运行时堆栈使一种特殊的数组,用于暂时保存地址和数据。ESP寄存器保存了一个32位偏移量,指向栈中某个位置。由于堆栈中的最后一个数是第一个出栈的,因此,堆栈被称为LIFO(先进先出)结构。入栈操作将一个数复制到堆栈。出栈操作将一个数从堆栈中取出并将其复制到寄存器或变量。堆栈通常存放过程返回地址、过程参数、局部变量和过程内使用的寄存器。
PUSH指令首先减少堆栈指针,然后把源操作数复制到堆栈中。POP指令首先把ESP指向的堆栈内容复制到目标操作数中,然后增加ESP的值。
PUSHAD指令把32位通用寄存器都压人堆栈,PUSHA指令把16位通用寄存器都压入堆栈。POPAD指令把堆栈中的数据弹出到32位通用寄存器中,POPA指令把堆栈中的数据弹出到16位通用寄存器中。POSHA和POPA只能用于16位编程。
PUSHFD指令将32位EFLAGS寄存器压入堆栈,POPFD将堆栈数据弹出到EFLAGS寄存器。PUSHF和POPF对16位FLAGS寄存器就行同样的操作。
RevStr程序(5.1.2节)用堆栈颠倒字符串顺序。
过程是用PROC和ENDP伪指令声明的、已命名的代码段,用RET指令结束其执行。5.1.2节中给出的SumOF过程,计算了三个整数之和。CALL指令通过将过程地址插入指令指针寄存器来执行这个过程,计算了三个整数之和。CALL指令通过将过程地址插入指令指针寄存器来执行这个过程。当过程执行结束时,RET(从过程返回)指令又将处理器带回到程序中过程被调用的位置。过程嵌套调用是指,一个调用过程在其返回前又调用了另一个过程。
带单个冒号的代码标号只在包含它的过程中可见。带::的代码标号则是全局标号,其所在源程序文件中的任何一条语句都可以访问它。
5.2.5节给出的ArraySum过程计算并返回了数组元素之和。
与PROC伪指令一起使用的USES运算符,列出了过程修改的全部寄存器。汇编器产生代码,在程序开始时将寄存器的内容压入堆栈,并在过程返回前弹出恢复寄存器。
来源:CSDN
作者:料理码王
链接:https://blog.csdn.net/qq_37150711/article/details/103984886