【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

相关文章

使用MongoDB进行数据存储的操作流程

《使用MongoDB进行数据存储的操作流程》在现代应用开发中,数据存储是一个至关重要的部分,随着数据量的增大和复杂性的增加,传统的关系型数据库有时难以应对高并发和大数据量的处理需求,MongoDB作为... 目录什么是MongoDB?MongoDB的优势使用MongoDB进行数据存储1. 安装MongoDB

Golang的CSP模型简介(最新推荐)

《Golang的CSP模型简介(最新推荐)》Golang采用了CSP(CommunicatingSequentialProcesses,通信顺序进程)并发模型,通过goroutine和channe... 目录前言一、介绍1. 什么是 CSP 模型2. Goroutine3. Channel4. Channe

利用Python编写一个简单的聊天机器人

《利用Python编写一个简单的聊天机器人》这篇文章主要为大家详细介绍了如何利用Python编写一个简单的聊天机器人,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 使用 python 编写一个简单的聊天机器人可以从最基础的逻辑开始,然后逐步加入更复杂的功能。这里我们将先实现一个简单的

使用IntelliJ IDEA创建简单的Java Web项目完整步骤

《使用IntelliJIDEA创建简单的JavaWeb项目完整步骤》:本文主要介绍如何使用IntelliJIDEA创建一个简单的JavaWeb项目,实现登录、注册和查看用户列表功能,使用Se... 目录前置准备项目功能实现步骤1. 创建项目2. 配置 Tomcat3. 项目文件结构4. 创建数据库和表5.

使用PyQt5编写一个简单的取色器

《使用PyQt5编写一个简单的取色器》:本文主要介绍PyQt5搭建的一个取色器,一共写了两款应用,一款使用快捷键捕获鼠标附近图像的RGB和16进制颜色编码,一款跟随鼠标刷新图像的RGB和16... 目录取色器1取色器2PyQt5搭建的一个取色器,一共写了两款应用,一款使用快捷键捕获鼠标附近图像的RGB和16

shell脚本快速检查192.168.1网段ip是否在用的方法

《shell脚本快速检查192.168.1网段ip是否在用的方法》该Shell脚本通过并发ping命令检查192.168.1网段中哪些IP地址正在使用,脚本定义了网络段、超时时间和并行扫描数量,并使用... 目录脚本:检查 192.168.1 网段 IP 是否在用脚本说明使用方法示例输出优化建议总结检查 1

四种简单方法 轻松进入电脑主板 BIOS 或 UEFI 固件设置

《四种简单方法轻松进入电脑主板BIOS或UEFI固件设置》设置BIOS/UEFI是计算机维护和管理中的一项重要任务,它允许用户配置计算机的启动选项、硬件设置和其他关键参数,该怎么进入呢?下面... 随着计算机技术的发展,大多数主流 PC 和笔记本已经从传统 BIOS 转向了 UEFI 固件。很多时候,我们也

基于Qt开发一个简单的OFD阅读器

《基于Qt开发一个简单的OFD阅读器》这篇文章主要为大家详细介绍了如何使用Qt框架开发一个功能强大且性能优异的OFD阅读器,文中的示例代码讲解详细,有需要的小伙伴可以参考一下... 目录摘要引言一、OFD文件格式解析二、文档结构解析三、页面渲染四、用户交互五、性能优化六、示例代码七、未来发展方向八、结论摘要

Java汇编源码如何查看环境搭建

《Java汇编源码如何查看环境搭建》:本文主要介绍如何在IntelliJIDEA开发环境中搭建字节码和汇编环境,以便更好地进行代码调优和JVM学习,首先,介绍了如何配置IntelliJIDEA以方... 目录一、简介二、在IDEA开发环境中搭建汇编环境2.1 在IDEA中搭建字节码查看环境2.1.1 搭建步

使用JavaScript操作本地存储

《使用JavaScript操作本地存储》这篇文章主要为大家详细介绍了JavaScript中操作本地存储的相关知识,文中的示例代码讲解详细,具有一定的借鉴价值,有需要的小伙伴可以参考一下... 目录本地存储:localStorage 和 sessionStorage基本使用方法1. localStorage