【MASM汇编语言快速入门】MASM常用伪指令速查表

您所在的位置:网站首页 汇编语言常用的编译器 【MASM汇编语言快速入门】MASM常用伪指令速查表

【MASM汇编语言快速入门】MASM常用伪指令速查表

2024-07-15 12:56| 来源: 网络整理| 查看: 265

MASM伪指令速查表–变量

初学MASM时, 常常看不懂db, dup(?)等汇编指令的含义, 教材中也缺乏系统的解释。与机器指令不同,这些指令叫伪指令, 在编译(汇编)的时候被MASM编译器处理, 而在运行时计算机不会真正的执行这些指令。这篇文章可以系统的解决对MASM伪指令的困扰。 MASM学习到这一块才叫真正的MASM,之前学习的机器指令都属于各种汇编语言都支持的8086指令集, 而这些伪指令只有MASM有, 别的汇编语言比如NASM等是不支持这些伪指令的。

文章目录 MASM伪指令速查表--变量一. 数值型参数(常量)和表达式1. 常量(常数)定义`equ`或`=`2. 数值表达式 二. 变量定义伪指令1. `db/dw/dd/df/dq/dt`2. 初值表和`dup`3. 定位伪指令`org`,`even`,`allign`(1) `org`(2) `even/align` 三. 变量的地址和类型1. 地址操作符 `offset` `seg`2. 地址操作符`:`, `[]`, `$`3. 类型操作符`ptr`, `this`, `type`(1) `ptr`(2) `this`(3) `TYPE`, `lengthof`, `sizeof`

一. 数值型参数(常量)和表达式 1. 常量(常数)定义equ或=

格式: [常量名] equ [值] 或者[常量名] = [值]

举例:

myid equ 1234 numofchina =1 ;一个中国 calldos equ ;[值]可以是字符串, 但是字符串要拿括起来

注意:

这里定义的是常量, 在内存中没有分配空间, 因此和高级语言(如c语言)的常量一样myid equ myid+1这种语句是不允许的

2. 数值表达式

masm6.x支持多种运算符, 对的你没有看错, MASM还可以支持运算符, 但是仅限常量和立即数的计算(和c语言的宏同理, 就是在编译的时候算好), 不能运行时计算

运算符类型算术运算符+, -, *, /, MOD(取余)逻辑运算符AND, OR, XOR(异或), NOT移位运算符SHL(左移), SHR(右移)关系运算符EQ(equal相等), NE(not equal不相等), GT(greater than大于), LT(less than小于), GE(大于等于), LE(小于等于)高低分离符HIGH(高字节), LOW(低字节), HIGHWORD(高字), LOWWORD(低字)

举例:

mov ax, 1*1+2 ; 等价于mov ax, 3 mov al, 0101b shl (2*2) ; 等价于 mov al, 01010000b(0101b左移四位) mov ah, high 8765h ; 等价于 mov ah, 87h(8765h的高字节) 二. 变量定义伪指令 1. db/dw/dd/df/dq/dt

db是以字节(8比特)为单位, dw是以字为单位(16比特), dd是双字, df是三字, dq是四字, dt是十字

格式: [变量名] db [初值表]

功能: 定义以字节为单位的变量,变量的起始地址为[变量名], 值为[初值表]中每个逗号隔开的元素, [变量名]可以省略

示例:

.data X db 'A', -5 db 2dup(100), ? Y db 'ABC' Z dw 'ABC'

说明:

db和dw是以某个长度为单位

Y在内存中为: 41h, 42h, 43h

Z在内存中为: 41h, 42h, 43h, 00h(因为以字为单位所以会有一个字节空出来)

2. 初值表和dup

初值表: 由逗号隔开的参数, 可以由数值, 表达式或"?", "dup"组成, "?"代表初值不确定即未赋值, 下面解释dup

格式: [次数]dup([初值])

功能: 定义[次数]个初值为[初值]的变量

示例:

.data X db 1, 3dup(0), 1 ; 在内存中就是01 00 00 00 01h Y db 2dup(?) ; 在内存中就是 ?? ?? h (?就是初值不确定,就是定义的时候我不在意初始值是多少,至于具体的值和编译器和版本有关, 大部分版本的MASM初始化?为0) 3. 定位伪指令org,even,allign (1) org

格式: org [偏移地址]

功能: 使他后面的数据或指令从指定的偏移地址开始

示例:

org 100h array db 12, 34, 56 ;12开始的偏移地址是100h, 或者说array的偏移地址是100h len equ $-array

解释: $的含义就是当前偏移地址的值例如

用途: 更细粒度的规划内存的空间, 可以任意指定程序和数据在虚拟内存中的结构,这是高级语言做不到而汇编能做到的. 比如开机时操作系统的引导程序(引导程序就是把操作系统逐步加载到内存中, 并进行一些初始化的程序), BIOS规定要将引导程序加载到07c00h这个地址上, 这样细粒度的内存空间管理只有汇编能做到, 这也是为什么操作系统的引导模块都会含有汇编程序, 而这样的功能就是用org 07c00h实现的

(2) even/align

功能:

even使后面的数据或指令地址从偶数开始

align [n]使后面的数据或地址从n的整数倍开始, 举例:align 4

用途:

用于数据对齐, 学过计算机组成原理的应该知道, 目的就是让数据对的更齐, 这样能最大减少取数据时总线传输次数消耗尽量少的总线时钟周期,通俗来讲就是取数据更快

三. 变量的地址和类型 1. 地址操作符 offset seg

格式:offset [标号/变量名] seg [标号/变量名]

功能:offset:取[标号/变量名]的偏移地址,seg:取[标号/变量名]的段基址

举例:

.model small ; 套话 org 100h ; 代码段的偏移地址设定为100h, 也就是hello的偏移地址为100h .data hello db 'ABC' ; hello是变量名 .code org 200h ; 设定nihao的偏移地址为200h nihao: ; nihao是标号 mov ax, offset hello ; 等价于 mov ax, 100h(hello的偏移地址) mov ax, seg nihao ; 等价于 mov ax, cs(因为nihao在代码段, seg是返回段基址) 2. 地址操作符:, [], $ []:$格式举例[ax+4300h]cs:[bx+1]mov ax, $+1功能[]表示将括号里面的表达式作为存储器地址的指针:表示用:前的段寄存器作为段超越的段寄存器, 段超越就是指不使用默认的段寄存器$表示当前位置的数据/指令的偏移地址 3. 类型操作符ptr, this, type (1) ptr

格式: [类型名] ptr [名字/标号/内存地址]

功能: 可以简单理解成C语言中的强制类型转换, 指定[名字/标号/内存地址]的类型为[类型名] (和高级语言的类型的含义不同,这里的变量类型就是指数据的宽度, 不过其实c语言区分变量类型的方法其实就是通过数据的宽度, 但是其他语言尤其是面向对象的语言比如python并不是靠数据宽度区分变量类型的)

举例:

.model small ; 套话 .data ; 定义数据段 w_var dw 01h ; 定义字(16比特)变量w_war .code ; 定义代码段 .startup ; 代码执行开始位置 mov al, byte ptr w_var ; w_var是字变量, byte ptr使得 w_var被当做字节变量 mov ah, bye ptr [1000h] ; 内存单元是以字为单位的, byte ptr使得 [1000h]的内存单元被当做字节变量 .exit 0 ; 套话 进程返回和中断

[类型名]还可以是:

byte(字节8比特), word(字16比特), dword(双字), fword(三字), qword(四字), tbyte(十比特), near(段内转移, 一般说明某个转移内存地址是比较近的), far(段间转移, 一般说明某个转移内存地址在别的段, 或者在本段非常远的位置), struct(结构体, 后面会细讲), record(记录, 学过数据库或者计算机组成原理应该会知道是什么意思, 不知道可以百度), union(联合体, 和c语言的union几乎一样)

(2) this

强制类型转换可以用PTR来实现.但是,如果程序中经常要以同一个数据宽度访问变量, 每次访问都要加上ptr操作符, 很麻烦, 于是,汇编语言提供了另外一种操作符:THIS,它为一个变量取了别名,该别名具有指定的和元变量不同的数据宽度,但是段地址和偏移量和原来的变量一致(也就是用固定用另外一种数据长度来访问原变量)

举例:

.data char equ this byte ; 这样写就可以通过char这个名字固定以字节为单位访问string, 想用字为单位访问就用string这个名字 string dw 'ABCDEFG' ; 定义以字为单位的变量string (3) TYPE, lengthof, sizeof

sizeof可以简单理解成c语言中的sizeof()关键字, sizeof = lengthof * type

type的返回值

类型返回值变量每个数据占用的字节数结构体结构体每个元素占用的字节数常数0标号代号(如near 为 0ff02h)寄存器寄存器宽度的字节数

举例

.data b_var equ this byte ; b_var是w_var的别名, 和w_var不一样的是, b_var以字节为单位访问 w_var dw 10 dup(0) ; 定义w_var是一个以字为单位有10个元素(值为0)的数组 .code mov ax, type w_var ; 等价于 mov ax, 2(两个字节, 也就是一个字) mov ax, type b_var ; 等价于 mov ax, 1(一个字节)


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3