前言
- 各位师傅大家好,我是qmx_07,今天给大家讲解16asm语法
环境配置
通过dosbox中的debug 编写asm汇编程序 比较繁琐,所以接下来我们使用vs code编写
- VS下载页面链接
- 配置选项
- 安装中文界面
- 配置asm环境
https://pan.baidu.com/s/1XBiaXwQwUXzADuSSNHDuWw
提取码c2u2
将ml.exe 和masm.exe,dosxint.exe放入 映射文件夹
- 编写自动化编译脚本
ml /c test.asm//编译源文件
link test.obj//链接obj文件
debug test.exe//使用debug调试程序
保存为build.bat程序
- 编译汇编程序
CODE SEGMENT ;USE16
ASSUME CS:CODE
BEG: MOV DL,'H'
MOV AH, 2 ; 调用2号DOS系统调用输出字符到屏幕上
INT 21H
MOV AH, 4CH
INT 21H
CODE ENDS
END BEG
- 如果执行test.exe,可以看到字符输出,说明配置成功
入口和段
- 段:将内存空间划分为不同的逻辑区域,用于存放不同类型的数据或代码,程序通常有:代码段(code segment)、数据段(data segment)和堆栈段(stack segment)
格式:
code segment //code是任意取名,并不固定
内容
code ends
演示:
- 入口点:程序开始执行的地方,类似于main,winmain
- 使用指定关键字end,后面跟标号名
2.入口点可以写在任意的段外面,一般写在文件末尾
data_seg segment
mov ax,ax
mov ax,ax
mov ax,ax
mov ax,ax
data_seg ends
data_seg1 segment
mov bx,bx
mov bx,bx
mov bx,bx
mov bx,bx
data_seg1 ends
data_seg2 segment
mov cx,cx
mov cx,cx
START://入口点 标号名
mov cx,cx
mov cx,cx
data_seg2 ends
end START//选择入口点
演示:
观察程序底层
- 指令对齐:当程序中的指令序列长度不满足 16 位边界要求时,编译器或汇编器会插入00来使指令流在内存中按照 16 位对齐
注释
- 汇编中使用;使用行注释
注意:汇编中没有块注释
常量
整数:
- 支持多个进制
- 必须以数字开头,如果是非数字,前面要加0(十六进制),例如:0ah
- 负数前面加-号
字符:
- 使用单引号(')或双引号(“”)
mov byte ptr[bx],'$'
变量
- 整数
- 整数支持多个类型
- 整数可以有多个初值,未初始化用?表示(数组)
- 变量一般定义在单独的段中
变量名 类型 初始值
val dd 5566h
演示:
- 变量存储过程
错误的变量赋值
- 可以观察到 al和bx内容并不正确,需要指定段偏移
正确的变量赋值
- 通过assume 通知 如果寻找变量,就从data_seg查找
mov ax,code
mov ds,ax
- 由于段寄存器 需要 程序运行 才有确定值,所以需要再进行赋值
字符串:
- 字符串都可以用单引号(')或双引号(“”)
- 字符串一般以美元符$结尾
g_sz db "hello world$"
数组:
格式:
名字 类型 值1,值2,值3...
名字 类型 数量dup(初值)
例子:
g_db db 78h,96h,'a'
g_ary db 256 dup(0),128 dup(11h);重复256个0,128个11
属性:
- masm提供了很多伪指令,可以获取变量的大小和地址,称之为变量的属性
演示:
堆栈:
- stack关键字让程序被加载时 指定ss、bp和sp
- 使用数组为栈设置大小
stack_seg segment stack //设置stack 会自动设置ss,bp和sp
db 256 dup(0cch);为栈申请大小空间
stack_seg ends
code_seg segment
START:
assume ds:data_seg,ss:stack_seg //设置ss段
mov ax,data_seg
mov ds,ax
push ax
push bx
push cx
push dx
pop ax
pop bx
pop cx
pop dx
code_seg ends
end START
注意:堆栈段 要放在代码最上方
演示:
调用dos功能号
功能号:
- dos系统提供的功能(API),通过21号中断来调用
- 每个功能都有一个编号,通过AH指定功能号
- 每个功能的参数需要查看手册
显示字符串
data_seg segment
g_hello db "hello world$"
data_seg ends
code_seg segment
START:
assume ds:data_seg
mov ax,data_seg
mov ds,ax
mov ah,09 //调用09显示字符串功能
mov dx,offset g_hello //获取g_hello的偏移地址,赋值给dx
int 21h//触发dos命令
code_seg ends
end START
自然退出程序
第一种退出方式:
mov ah,4ch
mov al,00
int 21h
第二种退出方式:
mov ax,4c00
int 21h
例子:
底层原理
中断:
- 中断是由cpu提供给的流程跳转指令,类似于函数调用
- 在00:00位置存储着一个双字数组,大小为256,称作中断向量表
- 数组元素为逻辑地址 段基址:段偏移
- int n的意思是从第n个元素获取地址,然后跳转执行
总结
- 介绍了 asm环境配置、入口和段、注释、常量、变量、调用dos功能号