• 忘掉天地
  • 仿佛也想不起自己
bingliaolongBingliaolong  2025-08-04 20:05 Aet 隐藏边栏 |   抢沙发  4 
文章评分 1 次,平均分 5.0

基础

NASM

  1. 开源、跨平台汇编器(支持 WindowsLinuxmacOS
  2. 特点
    1. 语法简洁严格(如内存访问必须用 [ ] 包裹)
    2. 无自动类型推断(需显式指定操作数大小,如 mov word [var], 1
    3. 支持直接生成纯二进制文件(如引导扇区程序)
  3. 应用
    1. 操作系统开发、嵌入式系统、跨平台项目

MASM

  1. 微软商业汇编器,深度集成于 Windows 生态(如 Visual Studio
  2. 特点
    1. 语法宽松(如内存访问可省略 [ ],支持 mov ax, table[di]
    2. 自动类型推断(如 mov [var], 1 能识别 var 类型)
    3. 提供高级伪指令(如 ASSUME 关联段寄存器)
  3. 应用
    1. Windows 驱动开发、与 C/C++ 混合编程

对比

  1. 不同的汇编器,它们的核心目标相同:将人类可读的汇编源代码(.asm文件)翻译成处理器可执行的机器码(包含在.obj或特定格式文件中)
    1. 一条 MOV EAX, EBX 在正确的上下文中,经过任何一个汇编器都会产生相同的机器码(如 89 D8 for 32-bit
  2. NASMMASM在语法层面存在差异

其他汇编

  1. FASM(Flat Assembler)
    1. 轻量、跨平台(Windows/Linux)、支持直接生成二进制文件(如引导扇区)
  2. GoASM
    1. 专为 Windows 设计,简化 Win32 API 调用,语法接近 MASM
  3. GAS
    1. Linux 生态默认汇编器,采用 AT&T 语法(与 Intel 语法差异大)

MASM环境配置

参考

  1. https://bbs.kanxue.com/thread-285079.htm

masm32

  1. 下载
    1. https://www.masm32.com/download.htm
    2. Australia 1
  2. 安装
    1. 解压安装程序,点击地球上的Install
  3. 后续
    1. 经过一系列点击,在控制台编译二进制文件
  4. masm32下的bin目录添加到path
    1. 新建include,将masm32目录下的inclcude目录添加进去
    2. 新建lib,将masm32目录下的lib目录添加进去
    3. 实践:includelib添加到了用户环境变量

测试代码

代码

编译1

  1. ml
    1. MASM 编译器的可执行文件名
    2. 调用 Microsoft 的汇编器
      负责将人类可读的汇编语言源代码(.asm 文件)翻译成机器可读的目标文件(.obj 文件)
  2. /c
    1. 只编译(Assemble Only),不链接(Do Not Link
    2. 为什么/c?
      开发较大项目时,程序通常由多个模块(源文件)组成。需要先单独编译每个模块(/c 为每个 .asm 文件生成 .obj 文件)
      或者,当需要链接多个目标文件或链接外部库时
      或者,只想确认汇编代码语法是否正确,而不需要生成最终的可执行文件
  3. MASMml 程序实际上既包含汇编器也包含链接器的功能
    1. 默认情况下,如果你只给 ml 一个 .asm 文件(像 ml test.asm),它会:
    2. test.asm 汇编成 test.obj(目标文件)
    3. 然后自动调用内置的链接器(link.exe),尝试将 test.obj 链接成可执行的 .exe 文件(或 .dll
    4. 在这个命令 ml /c /coff test.asm 中,使用 /c 明确告诉 MASM:“只需把 test.asm 编译成目标文件 test.obj,不要尝试链接生成 .exe.dll
  4. /coff
    1. 指定目标文件的格式为 COFFCommon Object File Format
    2. 目标文件(.obj)需要遵循特定的二进制格式标准。/coff 选择 MicrosoftCOFF 格式
      COFF 格式是生成 PEPortable Executable) 文件(即 Windows 操作系统使用的 .exe.dll.sys 等可执行或库文件格式)的基础
      链接器(link.exe)需要 COFF 格式的目标文件才能正确地将其组装成 PE 文件
  5. 可选格式
    1. MASM 以前支持 /omfOMF - Object Module Format)目标文件格式,主要用于一些较旧的 DOS/Win16 开发环境
    2. 现代 32 位(x86)及 64 位(x64Windows 开发都应使用 /coff

编译2(拓展)

  1. 编译并直接生成可执行文件(一步到位)
    1. MASM 会先汇编 test.asm 生成 test.obj(这一步隐式包含了 /c 的行为)
    2. 然后 MASM 会自动调用链接器 link.exe,传递给它生成的 test.obj 文件、指定的库文件(kernel32.lib, user32.lib)和链接选项(/subsystem:console
    3. 最终会生成一个 test.exe 可执行文件(控制台应用程序)

链接

  1. 使用 Microsoft Linker (link.exe) 将 目标文件(.obj) 链接成 Windows 可执行文件(.exe) 的关键步骤
  2. link
    1. Microsoft 链接器 (link.exe) 的可执行文件名
    2. 它的核心任务是将一个或多个目标文件(.obj) 以及库文件(.lib) “粘合”在一起,解决程序各部分之间的引用关系(比如函数调用、全局变量的访问),并最终输出一个符合特定操作系统格式(如 ~格式)的可执行文件(.exe) 或动态链接库(.dll)
  3. /subsystem:windows
    1. 明确指定要生成的可执行文件类型为图形用户界面 (GUI) 应用程序
  4. Windows 程序主要有两种运行方式
    1. /subsystem:console
    2. /subsystem:windows

16位与32位汇编

核心硬件差异

特性 16位汇编 32位汇编
寄存器宽度 16位(如 AX, BX, CX, DX 32位(扩展为 EAX, EBX, ECX, EDX
地址总线宽度 20位(最大寻址 1MB 32位(最大寻址 4GB
通用寄存器 8个(AX, BX, CX, DX, SI, DI, BP, SP 8个扩展为32位 + 新增8个(如 EBP, ESP
段寄存器 4个(CS, DS, ES, SS 6个(新增 FS, GS

内存寻址模式

  1. 16位(实模式)

  1. 32位(保护模式)

工作模式差异

模式 16位环境(实模式) 32位环境(保护模式)
特权级 无特权级,直接访问硬件 4级特权(Ring 0~3),限制硬件访问
内存保护 ❌ 无隔离(所有程序可写任意内存) ✅ 通过段描述符权限位保护内存
多任务支持 ❌ 需自行切换任务 ✅ 硬件级任务切换(TSS 任务状态段)
中断处理 直接修改 IVT(中断向量表) 通过 IDT(中断描述符表)及特权检查

指令集扩展

  1. 32位指令在16位基础上新增操作:
  2. 扩展寄存器操作:

  1. 新寻址方式:

  1. 系统指令:

MASM语法

特点

  1. 开发环境
    1. 微软官方工具链成员,与 Visual Studio 无缝集成(项目类型 .asm 可编译调试)
    2. 通过 .inc 包含文件(如 kernel32.inc, user32.inc)直接调用系统函数
  2. 语法宽松
    1. 变量定义后无需显式指定操作数大小(如 mov [var], 1 根据 var 定义自动识别 byte/word/dword
    2. mov ax, var 等效于 mov ax, [var]NASM 强制要求 [ ]
    3. 不区分大小写,MyLabelmylabel 视为同一符号

基础语法

  1. 程序框架伪指令

  1. 变量与数据定义
伪指令 含义 示例
DB 定义字节 age DB 25
DW 定义字(2字节) counter DW 1000
DD 定义双字(4字节) pointer DD 0x00400000
DQ 定义四字(8字节) bigNum DQ 1234567890
DT 定义十字节 float DT 3.1415926535
DUP 重复初始化 buffer DB 100 DUP(?)
  1. 表达式与运算符

核心语法

  1. 内存访问的宽松性

  1. ASSUME 伪指令(段关联)
    1. 编译器据此生成正确的段前缀(如 mov eax, [ebx] 自动添加 DS: 前缀)

  1. 过程函数定义

  1. 结构体

文档

  1. https://learn.microsoft.com/en-us/cpp/assembler/masm/directives-reference?view=msvc-170
    1. pdf下载

固定头

  1. 8086286都是16位的,从386开始是32位,后缀+P的指可以使用跳转指令的(适用于面向内核)

casemap

  1. ALL
    1. /Cu
    2. Map all identifiers to upper case
    3. 所有标识符转大写-大小写不敏感
  2. NONE
    1. /Cp
    2. Preserve case of user identifiers
    3. 所有标识符保持原有大小写-大小写敏感
  3. NOTPULIC
    1. /Cx
    2. Preserve case in publice, externs

分段

  1. 32位汇编取消 了分段,改用内存属性来划分,称作节(section)、内存区或内存块
    1. 编写时每种类型可以定义多个,编译期会自动被同类归置
  2. .DATA
    1. 可读、可写
    2. 初始化的全局变量
  3. .CONST
    1. 可读
    2. 只读数据区
  4. .DATA?
    1. 可读、可写
    2. 未初始化的全局变量
  5. .CODE
    1. 可读、可执行
    2. 代码

段寄存器

  1. 实模式(16位)
    1. 段寄存器存储的是段基址的高16位,物理地址计算为:
    2. 此时段寄存器仅作为地址计算组件,不参与内存保护

  1. 保护模式(32位)
    1. 段寄存器存储的是段选择子(Selector),本质是索引编号:
    2. 段选择子 = 索引号(13位) + TI标志(1位) + RPL权限(2位)
    3. 索引号:指向全局描述符表(GDT)或局部描述符表(LDT)的条目
    4. 描述符:包含32位段基址、段界限、访问权限等
    5. 16位段寄存器通过索引描述符表间接扩展为 32位段基址

  1. 长模式(64位)
    1. CS/SS/DS/ES 被强制设为 0(平坦内存模型,偏移地址直接寻址全64位空间)
    2. FS/GS 仍可自定义基址(通过MSR寄存器加载64位基址)
    3. FS/GS外,其他段寄存器失效,FS/GS通过64位基址扩展寻址能力

声明:本文为原创文章,版权归所有,欢迎分享本文,转载请保留出处!

bingliaolong
Bingliaolong 关注:0    粉丝:0 最后编辑于:2025-08-05
Everything will be better.

发表评论

表情 格式 链接 私密 签到
扫一扫二维码分享