Devld

8086 汇编笔记 - 程序代码结构 - 02

汇编

这里的汇编是 16位汇编, 在 Win7 64位 及以后已经不支持 目前有两种方法: 一是使用虚拟机, 另外就是 安装一个 DosBox 工具合集: AsmTool.zip 包含: masm 5和6 以及 DosBox

先来一个 Hello World

ASSUME CS:CODE      ; 声明代码段

DATA SEGMENT        ; 数据段
    HELLOWORLD   DB 'Hello World', '$'    ; HelloWorld 字符串
DATA ENDS

STACK SEGMENT STACK ; 堆栈段
    DB 32 DUP(0)    ; 声明一个32 bytes的连续空间当作堆栈段
STACK ENDS

CODE SEGMENT        ; 代码段
START:
    MOV AX, DATA    
    MOV DS, AX      ; 设置 DS 为数据段

    MOV AH, 09H
    MOV DX, OFFSET HELLOWORLD
    INT 21H         ; 调用 DOS 的中断, 将DX 指向的字符串打印出来

    MOV AX, 4C00H
    INT 21H         ; 程序退出
CODE ENDS
END START           ; 汇编结束,  并表示 程序起始位置为 标号 START 处

简化版 (MASM 6.x+)

.MODEL SMALL        ; 程序的存储模式
.STACK              ; 定义栈
.DATA               ; 定义数据段
	HELLOWORLD DB 'Hello World', '$'

.CODE               ; 定义代码段
.STARTUP            ; 定义程序起始位置

	MOV AH, 09H
	MOV DX, OFFSET HELLOWORLD
	INT 21H

.EXIT 0             ; 程序退出
	END               ; 汇编结束

程序存储模式 (MODEL)

.MODEL 存储模式 [, 语言类型] [, 操作系统类型] [, 堆栈选项]
模式代码段大小非代码段大小说明
TINY64kb64kb代码段和数据段的寄存器都被设置为同一值, 程序大小不能超过 64kb
SMALL64kb64kb只能有一个代码段和一个数据段, 程序最大 128kb
COMPACT64kb64kb+只能有一个代码段, 可以有多个数据段
MEDIUM64kb+64kb可以有多个数据段, 只能有一个代码段
LARGE64kb+64kb+代码段和数据段都可以有多个, 但全部的静态数据(不能改变的数据)仍限制在 64kb 内
HUGE64kb+64kb+与 LARGE 模式相同, 但静态数据没有限制
FLAT--只能运行在 32位的 x86 CPU上, DOS下无法使用. Windows 9.x, Windows NT 的程序必须使用此模式.

简化定义伪指令

  • 段定义

    ; 定义堆栈段, 段名为 STACK, 大小默认为 1kb
    .STACK [大小]
    
    ; 定义数据段, 段名是 _DATA. 用于定义变量
    .DATA
    
    ; 定义无初值变量段, 段名为 _BS. 使用这个可以减小 EXE文件大小
    .DATA ?
    
    ; 定义只读的常量数据段, 段名为 CONST
    .CONST
    
    ; 创建一个代码段
    .CODE [段名]
    
  • 程序开始伪指令

    .STARTUP
    

    .STARTUP 伪指令安装给定的 CPU 类型, 根据 .MODEL 选择的存储模式, 操作系统类型和堆栈类型, 产生程序开始执行的代码;同时指定了程序开始执行的起始位置. 在DOS 模式下, 它还会初始化 DS 的值, 调整 SS 和 SP 的值.

    在 SMALL 存储模式下, .STARTUP 会被编译成如下启动代码:

    MOV DX, DGROUP      ; DGROUP 表示数据段组的段地址
    MOV DS, DX
    MOV BX, SS
    SUB BX, DX
    SHL BX, 1
    SHL BX, 1
    SHL BX, 1
    SHL BX, 1
    CLI                 ; 关中断
    MOV SS, DX          ; 调整 SS = DS, 这是 SMALL 模式的规定
    ADD SP, BX          ; SP 也需要相应的调整
    STI                 ; 开中断
    
  • 程序结束未指定

    . EXIT [返回码]
    

    终止程序的的执行, 返回操作系统, 它对应的代码是

    MOV AX, 4C00H
    INT 21H
    
  • 汇编结束伪指令

    END [标号]
    

    指示汇编程序 MASM 到此结束汇编过程. 源程序最后一行必须有一条 END 指令, 可选的标号表示程序开始执行的位置. 例如 START, 连接程序据此设置 CS:IP 的值.