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

MASM伪指令速查表–变量

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

一. 数值型参数(常量)和表达式

1. 常量(常数)定义equ=

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

举例:

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

注意:

这里定义的是常量, 在内存中没有分配空间, 因此和高级语言(如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(一个字节)
  • 20
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值