【MASM汇编快速入门】最简单的汇编helloword与汇编程序框架:MASM伪指令速查表——存储模型和段的定义

本文主要是介绍【MASM汇编快速入门】最简单的汇编helloword与汇编程序框架:MASM伪指令速查表——存储模型和段的定义,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

最简单的汇编helloword与汇编程序框架:MASM伪指令速查表——程序结构和段的定义

文章目录

  • 最简单的汇编helloword与汇编程序框架:MASM伪指令速查表——程序结构和段的定义
  • 1. 简化段定义的格式
    • 0. 先看看简单且常用的汇编程序框架长什么样
    • 1. 存储模型伪指令`.model`
    • 2. 简化段定义伪指令`.data`, `.code`等
    • 3. 程序开始伪指令`.startup`
    • 4. 程序终止指令`.exit`
    • 5. 汇编结束伪指令`end`
    • small和tiny模式下的汇编程序模型
      • (1) small
        • 示例: 最简单的控制台输出hello world汇编程序, 比网上很多都短哦
      • (2) tiny
        • 示例, 程序实现按任意键后响铃:
  • 2. 完整段定义的格式
    • 0. 先看看完整段定义的汇编程序框架
      • 1. 完整段定义伪指令`segment`, `ends`
        • (1) 简单易懂款
        • (2) 复杂进阶款
      • 2. 指定段寄存器伪指令`assume`

1. 简化段定义的格式

前言: MASM提供了一系列简化段定义的伪指令, 这些指令使用起来比王爽书上介绍的完整段定义方式简单, 冗长的完整段定义方式既容易忘记又容易出错, 不适合学习和使用, 在实际上机过程中能减少很多麻烦. 尤其是初学的时候, 很多伪指令都没有学, 为了上机实验新学习的简单指令, 却需要查阅复杂的完整段定义方式写出完整的程序, 用到诸如segement, assume, ends, mov ax, 4c00h, int 21h之类的伪指令, 很多初学者都不知道是什么意思, 非常麻烦且容易出错. 当然如果是应付考试, 尤其是笔试, 还是要了解一下完整段定义的方式, 在这段简化段定义格式介绍完后, 下面还会介绍完整段定义的格式.

0. 先看看简单且常用的汇编程序框架长什么样

.model small.data
; 数据段.code
.startup
; 代码段.exit 0 
end

下面在逐步解释这些伪指令的含义

1. 存储模型伪指令.model

所谓存储模型就是定义了:一个汇编程序的规模,应该有哪些段,段的长度是多少,子程序调用数据访问指令转移的默认属性

格式: .model [存储模型] [语言类型] [操作系统类型] [堆栈选项]

在学习MASM的过程中我们一般只要第一个参数[存储模型], 主要关注有哪些段

存储模型一句话描述
TINY微型模型, 只有一个段, 代码段数据段堆栈段都在一个段内, 整个程序的数据加代码不大于64KB
SMALL小型模型, 只有代码段和数据段, 每个段长度不大于64KB, 即整个程序数据加代码不大于128KB
COMPACT紧凑模型, 只有一个代码段, 数据段可以有多个, 每个段长度不大于64KB跳转指针默认为FAR指针, 因为有多个数据段要区分
MEDIUM中型模型, 多个代码段, 数据段只有一个, 每个段长度不大于64KB, 同样默认FAR指针
LARGE大型模型, 多个段, 静态数据(常量等)限制在64KB以内
HUGE巨型模型, 多个段, 不限制静态数据
FLAT平展模型, 32位的汇编程序, 不能运行在DOS上

我们一般使用TINY或者SMALL就可以了, SMALL最方便

举例:

.model small
....

2. 简化段定义伪指令.data, .code

  1. .code ,.data, .stack分别表示代码段, 数据段, 堆栈段的开始, 一个段的开始自动结束前面的段, 就不用xxx segment, xxx ends这种指令把整个段包围了

  2. 注意: 采用简化段定义指令之前必须有.model语句

  3. 格式: .code [段名], .data / .data?, .stack[大小]

    .code默认段名是_TEXT, 在medium, large, huge模型下默认段名是模块名_TEXT

    .stack的默认大小是1KB

    .data的默认段名_DATA用来定义有初值的变量, .data?的默认段名是_BSS用来定义无初值的变量, 另外.const可以建立制度常量段, 段名为CONST

举例:

.model compact.data
a db 1.data?
b db ?.const
c db 2.code
.startup.exit 0
end

db指令看不懂啥意思可以看这篇文章【MASM快速入门】MASM常用伪指令速查表——变量-CSDN博客

3. 程序开始伪指令.startup

.startup伪指令按照制定的cpu类型, 之前.model指定的存储模型, 操作系统和堆栈, 产生程序开始执行的代码, 同时指定程序开始的起点, 可以简单的理解为程序的入口, 即程序从哪里开始执行

在小型模式中.startup等同于

mov dx, @data
mov ds, dx
mov bx, dx
shl bx, 1
shl bx, 1
shl bx, 1
shl bx, 1
cli				; 关中断
mov ss, dx
add sp, bx
sti				; 开中断

主要就是设置数据段寄存器ds的值, 同时按照.model的要求设置ss=ds(只有一个数据段)

这些指令看不懂可以看【MASM汇编语言快速入门】8086MASM机器指令速查-CSDN博客

4. 程序终止指令.exit

格式: .exit [终止码] 我们一般用.exit 0[终止码]为0代表正常退出, 没有错误

.exit 0等同于

mov ax, 4c00h		; DOS功能调用的4ch子功能
int 21h				; 调用DOS中断

5. 汇编结束伪指令end

格式:end [标号]

功能: 指示汇编程序MASM到此结束汇编过程, 源程序的最后必须有这条指令

small和tiny模式下的汇编程序模型

(1) small

.model small	; 定义内存模型为small.data			; 定义数据段, 在small模式下, 数据段和堆栈段共用在这个段
; 数据段内容xxx.code			; 定义代码段
.startup		; 定义程序入口
; 代码段内容xxx
.exit 0			; 程序正常退出end				; 汇编结束标志
示例: 最简单的控制台输出hello world汇编程序, 比网上很多都短哦
.model small
.data
string db 'hello, world!$'		
.code
.startup
mov dx, offset string
mov ah, 9
int 21h
.exit 0
end

(2) tiny

.model tiny		; 定义内存模型为tiny
.code			; 定义代码段, 在tiny模式下, 数据段堆栈段代码段全部共用在这个段
.startup
; 代码段内容xxx
.exit 0
; 数据定义在这里, 写在与代码不冲突的位置
end
示例, 程序实现按任意键后响铃:
.model tiny.code
.startup
mov dx, offset string	; 显示信息
mov ah, 9
int 21hmov ah, 01h				; 等待按键
int 21hmov ah, 02h				; 响铃
mov dl, 07h
int 21h
.exit 0string db 'Press any key to continue!$'	; 数据定义在这里
end

2. 完整段定义的格式

前言: 上面采用的是MASM提供的简化汇编程序的伪指令, 如果有特殊需求需要自定义程序结构, 或者是应付考试, 还是要学习完整段定义的方式. 但是实际上无论是在学习过程中, 还是实际使用过程中, MASM提供的简化段定义方式考虑到了大部分常用情况, 基本可以适用于大部分需求, 需要完整定义段的情况不多. 但是为了学习到所有可能的情况, 这里还是写出完整段定义的格式供大家学习参考

0. 先看看完整段定义的汇编程序框架

先给出框架, 下面逐步解释含义

stack segment...
stack endsdata segment...
data endscode segment 'code'assume cs:code, ds:data, ss:stack
start:mov ax, datamov ds, ax...mov ax, 4c00hint 21h...
code endsend start

1. 完整段定义伪指令segment, ends

(1) 简单易懂款
段名 segment 		  		; 段开始 
...						   ; 段内容
...
段名 ends					; 段结束
(2) 复杂进阶款

教材上一般介绍的比较全面会介绍各种选项参数, 但这容易让初学者看的云里雾里. 实际上大部分学校期末或者复试都不专门考这玩意, 试卷中出现了也无伤大雅, 并且在实际开发中, 无论是内联汇编还是反汇编都不常见到这种用法, 如果感兴趣或者有实际需要可以看看.

段名 segment [定位] [组合] [段字] ['类别']			
...
...
段名 ends
  1. [定位] 用于指定这个段开始的位置, 可选选项:
    1. byte(段开始为下个可用的字节),
    2. word(段开始为下个可用的字),
    3. dword(段开始为下个可用的四字),
    4. page(段开始为下个可用的逻辑页(虚页)地址)
  2. [组合] 用于指定这个段和其他段的关系, 汇编器通过这个字段决定要不要把本段与其他段合并
    1. private: 本段与其他段没有逻辑关系, 不与其他段合并
    2. public: 本段与所有同类型的段连接在一起
    3. stack: 堆栈的一部分, 链接程序将所有的stack段合并, 多模块汇编程序的堆栈段必须写出这种组合
    4. common: 连接程序把所有同名同类逻辑段指定一个段地址, 用于段共享
  3. [段字]为支持32位汇编程序的选项:
    1. 16位x86默认: USE16
    2. 32位x86默认: USE32
  4. [‘类别’]指定段的类型, 但是其实assume指令就指定了, 如果是多模块程序会用到
    1. ‘code’: 说明这个段是代码段
    2. ‘data’: 说明这个段是数据段
    3. ‘stack’: 说明这个段是堆栈段

2. 指定段寄存器伪指令assume

功能: 就是把定义的段和段寄存器绑定

格式: assume 段寄存器:段名, ....

举例:

stack segment				; 定义了一个段 这个段叫stack, 此时汇编器还不知道这是个堆栈段...
stack ends					; 这个叫stack的段定义结束data segment				; 定义了一个段 这个段叫data, 此时汇编器还不知道这是个数据段...
data ends					; 叫data的段定义结束code segment 'code'			; 定义了一个代码段('code'这个字段说明这是个代码段) 这个代码段叫codeassume cs:code, ds:data, ss:stack	; 把code这个段和cs代码段寄存器绑定, 也就是说code是个代码段, data, stack同理, 到这里汇编器才知道哪个是数据段和堆栈段
code ends					; 叫code的代码段定义结束

这篇关于【MASM汇编快速入门】最简单的汇编helloword与汇编程序框架:MASM伪指令速查表——存储模型和段的定义的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/806455

相关文章

C++初始化数组的几种常见方法(简单易懂)

《C++初始化数组的几种常见方法(简单易懂)》本文介绍了C++中数组的初始化方法,包括一维数组和二维数组的初始化,以及用new动态初始化数组,在C++11及以上版本中,还提供了使用std::array... 目录1、初始化一维数组1.1、使用列表初始化(推荐方式)1.2、初始化部分列表1.3、使用std::

使用Python快速实现链接转word文档

《使用Python快速实现链接转word文档》这篇文章主要为大家详细介绍了如何使用Python快速实现链接转word文档功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 演示代码展示from newspaper import Articlefrom docx import

0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeek R1模型的操作流程

《0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeekR1模型的操作流程》DeepSeekR1模型凭借其强大的自然语言处理能力,在未来具有广阔的应用前景,有望在多个领域发... 目录0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeek R1模型,3步搞定一个应

redis群集简单部署过程

《redis群集简单部署过程》文章介绍了Redis,一个高性能的键值存储系统,其支持多种数据结构和命令,它还讨论了Redis的服务器端架构、数据存储和获取、协议和命令、高可用性方案、缓存机制以及监控和... 目录Redis介绍1. 基本概念2. 服务器端3. 存储和获取数据4. 协议和命令5. 高可用性6.

Deepseek R1模型本地化部署+API接口调用详细教程(释放AI生产力)

《DeepseekR1模型本地化部署+API接口调用详细教程(释放AI生产力)》本文介绍了本地部署DeepSeekR1模型和通过API调用将其集成到VSCode中的过程,作者详细步骤展示了如何下载和... 目录前言一、deepseek R1模型与chatGPT o1系列模型对比二、本地部署步骤1.安装oll

Spring AI Alibaba接入大模型时的依赖问题小结

《SpringAIAlibaba接入大模型时的依赖问题小结》文章介绍了如何在pom.xml文件中配置SpringAIAlibaba依赖,并提供了一个示例pom.xml文件,同时,建议将Maven仓... 目录(一)pom.XML文件:(二)application.yml配置文件(一)pom.xml文件:首

修改若依框架Token的过期时间问题

《修改若依框架Token的过期时间问题》本文介绍了如何修改若依框架中Token的过期时间,通过修改`application.yml`文件中的配置来实现,默认单位为分钟,希望此经验对大家有所帮助,也欢迎... 目录修改若依框架Token的过期时间修改Token的过期时间关闭Token的过期时js间总结修改若依

JAVA调用Deepseek的api完成基本对话简单代码示例

《JAVA调用Deepseek的api完成基本对话简单代码示例》:本文主要介绍JAVA调用Deepseek的api完成基本对话的相关资料,文中详细讲解了如何获取DeepSeekAPI密钥、添加H... 获取API密钥首先,从DeepSeek平台获取API密钥,用于身份验证。添加HTTP客户端依赖使用Jav

如何在本地部署 DeepSeek Janus Pro 文生图大模型

《如何在本地部署DeepSeekJanusPro文生图大模型》DeepSeekJanusPro模型在本地成功部署,支持图片理解和文生图功能,通过Gradio界面进行交互,展示了其强大的多模态处... 目录什么是 Janus Pro1. 安装 conda2. 创建 python 虚拟环境3. 克隆 janus

Redis存储的列表分页和检索的实现方法

《Redis存储的列表分页和检索的实现方法》在Redis中,列表(List)是一种有序的数据结构,通常用于存储一系列元素,由于列表是有序的,可以通过索引来访问元素,因此可以很方便地实现分页和检索功能,... 目录一、Redis 列表的基本操作二、分页实现三、检索实现3.1 方法 1:客户端过滤3.2 方法