【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

相关文章

使用EasyPoi快速导出Word文档功能的实现步骤

《使用EasyPoi快速导出Word文档功能的实现步骤》EasyPoi是一个基于ApachePOI的开源Java工具库,旨在简化Excel和Word文档的操作,本文将详细介绍如何使用EasyPoi快速... 目录一、准备工作1、引入依赖二、准备好一个word模版文件三、编写导出方法的工具类四、在Export

MyBatis/MyBatis-Plus同事务循环调用存储过程获取主键重复问题分析及解决

《MyBatis/MyBatis-Plus同事务循环调用存储过程获取主键重复问题分析及解决》MyBatis默认开启一级缓存,同一事务中循环调用查询方法时会重复使用缓存数据,导致获取的序列主键值均为1,... 目录问题原因解决办法如果是存储过程总结问题myBATis有如下代码获取序列作为主键IdMappe

Java 缓存框架 Caffeine 应用场景解析

《Java缓存框架Caffeine应用场景解析》文章介绍Caffeine作为高性能Java本地缓存框架,基于W-TinyLFU算法,支持异步加载、灵活过期策略、内存安全机制及统计监控,重点解析其... 目录一、Caffeine 简介1. 框架概述1.1 Caffeine的核心优势二、Caffeine 基础2

k8s搭建nfs共享存储实践

《k8s搭建nfs共享存储实践》本文介绍NFS服务端搭建与客户端配置,涵盖安装工具、目录设置及服务启动,随后讲解K8S中NFS动态存储部署,包括创建命名空间、ServiceAccount、RBAC权限... 目录1. NFS搭建1.1 部署NFS服务端1.1.1 下载nfs-utils和rpcbind1.1

Linux五种IO模型的使用解读

《Linux五种IO模型的使用解读》文章系统解析了Linux的五种IO模型(阻塞、非阻塞、IO复用、信号驱动、异步),重点区分同步与异步IO的本质差异,强调同步由用户发起,异步由内核触发,通过对比各模... 目录1.IO模型简介2.五种IO模型2.1 IO模型分析方法2.2 阻塞IO2.3 非阻塞IO2.4

Python实现简单封装网络请求的示例详解

《Python实现简单封装网络请求的示例详解》这篇文章主要为大家详细介绍了Python实现简单封装网络请求的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录安装依赖核心功能说明1. 类与方法概览2.NetHelper类初始化参数3.ApiResponse类属性与方法使用实

Redis高性能Key-Value存储与缓存利器常见解决方案

《Redis高性能Key-Value存储与缓存利器常见解决方案》Redis是高性能内存Key-Value存储系统,支持丰富数据类型与持久化方案(RDB/AOF),本文给大家介绍Redis高性能Key-... 目录Redis:高性能Key-Value存储与缓存利器什么是Redis?为什么选择Redis?Red

MyBatis-plus处理存储json数据过程

《MyBatis-plus处理存储json数据过程》文章介绍MyBatis-Plus3.4.21处理对象与集合的差异:对象可用内置Handler配合autoResultMap,集合需自定义处理器继承F... 目录1、如果是对象2、如果需要转换的是List集合总结对象和集合分两种情况处理,目前我用的MP的版本

从入门到精通详解Python虚拟环境完全指南

《从入门到精通详解Python虚拟环境完全指南》Python虚拟环境是一个独立的Python运行环境,它允许你为不同的项目创建隔离的Python环境,下面小编就来和大家详细介绍一下吧... 目录什么是python虚拟环境一、使用venv创建和管理虚拟环境1.1 创建虚拟环境1.2 激活虚拟环境1.3 验证虚

GSON框架下将百度天气JSON数据转JavaBean

《GSON框架下将百度天气JSON数据转JavaBean》这篇文章主要为大家详细介绍了如何在GSON框架下实现将百度天气JSON数据转JavaBean,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下... 目录前言一、百度天气jsON1、请求参数2、返回参数3、属性映射二、GSON属性映射实战1、类对象映