汇编语言:基于x86处理器考前笔记 | 第三章 汇编语言基础

3.1 基本语言元素

  1. 程序框架
    • 程序从main PROC开始,到main ENDP结束,最后以END main标识程序入口与地址。
    • main PROC调用函数(子程序)ExitProcessmov eax, 5add eax, 6INVOKE ExitProcess, 0main ENDP
  2. 声明变量
    • 使用.data伪指令声明变量,如.data sum DWORD 0声明了32位变量sum,并可在程序中对其赋值,如mov sum,eax
  3. 整数常量表示
    • 十进制:如2626d
    • 二进制:如00011010b
    • 八进制:如32q32o
    • 十六进制:以数字开头可直接写,以字母开头需加前置“0”,如1AhB3h应写成0B3h
  4. 整数常量表达式与实数常量
    • 表达式如30 MOD (3 * 4)+(3 - 1)/2,结果可用32位存放(0到FFFFFFFF),包含整数常量与算数运算符,其优先级参考表3 - 1,圆括号优先级最高为1,一元加、减为2,乘、除和取模为3,加、减为4。
  5. 字符常量与字符串常量
    • 字符常量:如‘a’、“a”。
    • 字符串常量:如’ab c’、“a b c”,都可使用单引号和双引号。并给出了字符对应的Ctrl、Dec、Hex、Char、Code等详细信息,如Ctrl + A对应Dec为1、Hex为01、Char为SOH等。
  6. 保留字与标识符
    • 保留字:包括指令助记符(如MOV、ADD、JMP、CALL等)、寄存器名称、伪指令(关键字)、属性(BYTE、WORD)、运算符、预定义符(@data)等。
    • 标识符:程序员自定义名称,大小1到247,不区分大小写,但不能与保留字相同,建议使用描述性名称。

伪指令与指令

  1. 伪指令
    • 嵌入源代码中,由汇编器识别和执行,不在运行时执行,可用于定义变量、宏,为内存段分配名称等。如.data myVar DWORD 26,伪指令不区分大小写,.data.DATA.Data等效。
    • 伪指令含义
.386
.MODEL FLAT, STDCALL
.STACK 4096  
ExitProcess PROTO, dwExitCode: DWORD

.DATA
    ; 数据定义

.CODE
main PROC
    ; 程序主体
    INVOKE ExitProcess, 0
main ENDP

END main

  1. 指令
    • 标号(可选)、指令助记符(必须)、操作数(通常必须,个数0 - 3)、注释(可选)组成
    • 指令助记符:如MOV、ADD、JMP、CALL等,标记一条指令。
    • 操作数:指令输入输出的数值,如stc(无操作数)、inc eax(一个操作数)、mov count, ebx(两个操作数)。
    • 注释:是程序编写者与阅读者交流程序设计信息的重要途径,单行注释用分号(;)开始,汇编器忽略同一行上分号后的所有字符;多注释可用COMMENT开始,如COMMENT! This line is a comment This line is also a comment

3.2 add程序相关说明

  1. 程序开头的说明:.386表示这是一个32位程序;.model flat, stdcall选择flat内存模式,确认子程序调用规范(stdcall规范);.stack 4096表示堆栈保留4096字节存储空间。
  2. 函数声明:如ExitProcess PROTO, dwExitCode:DWORD表示给windows系统的返回值。

3.3汇编、链接和运行程序

  1. 相关概念
    • 汇编过程涉及程序****【记忆】:1️⃣汇编器将源文件转换为目标文件(.obj),2️⃣连接器把目标文件与链接库组合成可执行文件(.exe),3️⃣编译器将源程序翻译为机器语言。若程序存在对链接库的调用,链接器会进行相应处理。
    • 列表文件内容:包含源文件副本、行号、指令地址、指令代码字节、符号表等。例如给出的AddTwo.asm的列表文件详细展示了程序相关信息,如指令地址、指令代码字节等,可辅助程序调试。
  2. 环境搭建与调试【无需记忆】
    • 汇编调试环境搭建:可参考QQ群中的“VS2017搭建汇编调试环境.docx”和“VS2019搭建汇编调试环境.docx”文档。
    • 代码调试:参考P56 3.4.3的相关内容,通过调试可深入理解程序执行过程,帮助定位和解决程序中的问题。

3.4 定义数据

  1. 内部数据类型
    • 汇编器可识别多种内部数据类型,按照大小、是否有符号、整数或实数来分类,如BYTE(8位无符号整数)、SBYTE(8位有符号整数)、WORD(16位无符号整数)、DWORD(32位无符号整数)等。
  2. 数据定义规则
    • 定义数据至少要有1个初始值,可为0或?,多个初始值用,隔开,且必须是整数常量或变量,如count DWORD 1,2,3,4,5。
  3. 特殊情况处理
    • 多初始值定义:同一个数据定义中使用多个初始值时,标号只指出第一个初始值的偏移量,如list1 BYTE 10,20,30,40和list2 WORD 10,20,30,40的偏移量及对应数值情况。
    • 定义字符串:使用BYTE伪指令定义字符串,如greeting1 BYTE “Good afternoon”, 0greeting2 BYTE “Good night”, 0,可使用行连续字符()连接两行语句,如greeting1 BYTE “Good afternoon”greeting1 \ BYTE “Good afternoon”等价。
    • DUP操作符:用于分配内存空间并初始化,如BYTE 20 DUP(0)分配20个字节型内存空间且初始值为0,BYTE 20 DUP(?)分配空间但数据未初始化,count DW 40 DUP(1,2,3,4,5)定义了特定数据结构。
    • 小端顺序:x86处理器在内存中按从低到高存放和检索数据,如12345678h在内存中的存放方式为低字节在前高字节在后。

3.5 符号常量

  1. 等号伪指令定义:通过等号伪指令(=)为整数表达式或文本指定标识符来创建符号常量,如COUNT = 500,之后可在程序中使用该符号常量,如mov eax, COUNT在这里 count 就会被替代为 500。
  2. 计算数组和字符串大小使用$(当前地址计数器)计算数组和字符串大小,单位为字节。
    1. 求数组长度:例如list WORD 10,20,30,40,ListSize = ($ - list)/2 可计算出列表长度,这里数组要除以单个元素大小(即 2);
    2. 求字符串长度myString BYTE “This is a long string” , myStringLen = ($ - myString)可计算字符串长度。注意$只可跟在字符串后面,不然会出问题
  3. EQU 伪指令:将一个符号名称与一个整数表达式或文本连接起来。语法:name EQU expression,注意不能被重新定义
  4. **TEXTEQU 伪指令:**类似于 EQU,但用于创建文本宏。可以被重定义
回顾

3.1

1. 使用数值-35.按照MASM语法,写出该数值的十进制、十六进制、八进制和二进制格式的整数常量

  • 十进制:-35
  • 十六进制:-23h (注意:MASM不支持直接表示负数的十六进制常量,需要使用补码表示)
  • 八进制:-43o (注意:MASM不支持直接表示负数的八进制常量,需要使用补码表示)
  • 二进制:-100011b (注意:MASM不支持直接表示负数的二进制常量,需要使用补码表示)
    2. (是/否):A5h是一个有效的十六进制常量吗?
  • 是的,A5h 是一个有效的十六进制常量,表示十进制数值 165。
    3. (是/否):整数表达式中,乘法运算符(*)是否比除法运算符(/)具有更高优先级?
  • 否。在整数表达式中,乘法运算符(*)和除法运算符(/)具有相同的优先级。在没有括号的情况下,它们按照从左到右的顺序进行计算
    4. 编写一个整数表达式,要求用到3.1.2节中的所有运算符。计算该表达式的值
-10 + 20 * 3 MOD 4
  • 计算过程:
    1. 20 * 3 = 60
    2. 60 MOD 4 = 0
    3. -10 + 0 = -10
  • 表达式的值为 -10。
    5. 按照MASM语法,写出实数-6.2×10?的实数常量
  • -6.2E+0 (注意:MASM不支持指数形式的实数常量,需要使用科学计数法表示)
    6. (是/否):字符串常量必须被包含在单引号中吗?
  • 是的,字符串常量必须被包含在单引号或双引号中。
    7. 保留字可以用作指令助记符、属性、运算符、预定义符号,和___
  • 保留字可以用作指令助记符、属性、运算符、预定义符号,以及段名
    8. 标识符的最大长度是多少?
  • 标识符的最大长度为 247 个字符。

3.2

1. 在AddTwo程序中,ENDP伪指令的含义是什么

  • ENDP伪指令用于标记一个过程的结束。在AddTwo程序中,它用于标记main过程的结束。

2. 在AddTwo程序中,.CODE伪指令标识了什么

  • .CODE伪指令用于标识程序代码段的开始。在AddTwo程序中,它用于标识包含可执行指令的代码段。

3. AddTwo程序中两个段的名称是什么

  • AddTwo程序中包含两个段:
    • 数据段:未命名,由.data伪指令标识。
    • 代码段:未命名,由.code伪指令标识。

4. 在AddTwo程序中,哪个寄存器保存了和数

  • AddTwo程序中,EAX寄存器保存了和数。
    5. 在AddTwo程序中,哪条语句使程序停止
  • INVOKE ExitProcess, 0语句使程序停止。它调用ExitProcess函数,并将0作为参数传递,表示程序成功执行。

3.3

1. 汇编器生成什么类型的文件

  • 汇编器生成目标文件,扩展名为.obj。目标文件包含汇编语言程序翻译成的机器代码和相关信息,但尚未包含程序运行所需的所有资源。
    2. (真/假):链接器从链接库中抽取已汇编程序,并将其插入到可执行程序中
  • 。链接器会从链接库中抽取已汇编程序或模块,并将其插入到可执行程序中,形成完整的程序。
    3. (真/假):程序源代码修改后,它必须再次进行汇编和链接才能按照修改内容执行

  • 4. 操作系统的哪一部分来读取和执行程序
  • 操作系统的加载程序负责读取可执行程序并将其加载到内存中,然后使CPU执行程序。
    5. 链接器生成什么类型的文件
  • 链接器生成可执行文件,扩展名为.exe。可执行文件包含了完整的程序代码和数据,可以直接在操作系统上运行。

3.4

1. 用等号伪指令定义一个符号常量,使其包含Backspace键的ASCII码(08h)

BACKSPACE_KEY = 08h

2. 用等号伪指令定义符号常量SecondsInDay,并为其分配一个算术表达式计算24小时包含的秒数

SecondsInDay = 24 * 60 * 60

3. 编写一条语句使汇编器计算下列数组的字节数,并将结果赋给符号常量ArraySize:myArray WORD 20 DUP(?)

ArraySize = ($ - myArray)

4. 说明如何计算下列数组的元素个数,并将结果赋给符号常量ArraySize:myArray DWORD 30 DUP(?)

ArraySize = ($ - myArray) / 4

5. 使用TEXTEQU表达式将“proc”重定义为"procedure"

proc TEXTEQU 

6. 使用TEXTEQU将一个字符串常量定义为符号Sample,再使用该符号定义字符串变量MyString

Sample TEXTEQU <"This is a sample string.">          
MyString BYTE Sample

7. 使用TEXTEQU将下面的代码行赋给符号SetupESI:mov esi,OFFSET myArray

SetupESI TEXTEQU 
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/8b4c6cf30e934e518f1086cb79f02624.png)

你可能感兴趣的:(课程所学,笔记)