【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++11 <chrono> 库特性

《从入门到精通C++11<chrono>库特性》chrono库是C++11中一个非常强大和实用的库,它为时间处理提供了丰富的功能和类型安全的接口,通过本文的介绍,我们了解了chrono库的基本概念... 目录一、引言1.1 为什么需要<chrono>库1.2<chrono>库的基本概念二、时间段(Durat

Java中调用数据库存储过程的示例代码

《Java中调用数据库存储过程的示例代码》本文介绍Java通过JDBC调用数据库存储过程的方法,涵盖参数类型、执行步骤及数据库差异,需注意异常处理与资源管理,以优化性能并实现复杂业务逻辑,感兴趣的朋友... 目录一、存储过程概述二、Java调用存储过程的基本javascript步骤三、Java调用存储过程示

MySQL之InnoDB存储引擎中的索引用法及说明

《MySQL之InnoDB存储引擎中的索引用法及说明》:本文主要介绍MySQL之InnoDB存储引擎中的索引用法及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录1、背景2、准备3、正篇【1】存储用户记录的数据页【2】存储目录项记录的数据页【3】聚簇索引【4】二

MySQL之InnoDB存储页的独立表空间解读

《MySQL之InnoDB存储页的独立表空间解读》:本文主要介绍MySQL之InnoDB存储页的独立表空间,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、背景2、独立表空间【1】表空间大小【2】区【3】组【4】段【5】区的类型【6】XDES Entry区结构【

Spring 框架之Springfox使用详解

《Spring框架之Springfox使用详解》Springfox是Spring框架的API文档工具,集成Swagger规范,自动生成文档并支持多语言/版本,模块化设计便于扩展,但存在版本兼容性、性... 目录核心功能工作原理模块化设计使用示例注意事项优缺点优点缺点总结适用场景建议总结Springfox 是

SQLite3 在嵌入式C环境中存储音频/视频文件的最优方案

《SQLite3在嵌入式C环境中存储音频/视频文件的最优方案》本文探讨了SQLite3在嵌入式C环境中存储音视频文件的优化方案,推荐采用文件路径存储结合元数据管理,兼顾效率与资源限制,小文件可使用B... 目录SQLite3 在嵌入式C环境中存储音频/视频文件的专业方案一、存储策略选择1. 直接存储 vs

解析C++11 static_assert及与Boost库的关联从入门到精通

《解析C++11static_assert及与Boost库的关联从入门到精通》static_assert是C++中强大的编译时验证工具,它能够在编译阶段拦截不符合预期的类型或值,增强代码的健壮性,通... 目录一、背景知识:传统断言方法的局限性1.1 assert宏1.2 #error指令1.3 第三方解决

Linux如何快速检查服务器的硬件配置和性能指标

《Linux如何快速检查服务器的硬件配置和性能指标》在运维和开发工作中,我们经常需要快速检查Linux服务器的硬件配置和性能指标,本文将以CentOS为例,介绍如何通过命令行快速获取这些关键信息,... 目录引言一、查询CPU核心数编程(几C?)1. 使用 nproc(最简单)2. 使用 lscpu(详细信

从入门到精通MySQL 数据库索引(实战案例)

《从入门到精通MySQL数据库索引(实战案例)》索引是数据库的目录,提升查询速度,主要类型包括BTree、Hash、全文、空间索引,需根据场景选择,建议用于高频查询、关联字段、排序等,避免重复率高或... 目录一、索引是什么?能干嘛?核心作用:二、索引的 4 种主要类型(附通俗例子)1. BTree 索引(

Redis 配置文件使用建议redis.conf 从入门到实战

《Redis配置文件使用建议redis.conf从入门到实战》Redis配置方式包括配置文件、命令行参数、运行时CONFIG命令,支持动态修改参数及持久化,常用项涉及端口、绑定、内存策略等,版本8... 目录一、Redis.conf 是什么?二、命令行方式传参(适用于测试)三、运行时动态修改配置(不重启服务