汇编中标号与变量名的区别

转:blog.sina.com.cn/s/blog_78021ae10100vnwk.html

当程序中要跳转到另一位置时,需要有一个标识来指示新的位置,这就是标号,通过在目标地址的前面放上一个标号,可以在指令中使用标号来代替直接使用地址。
使用变量是任何编程语言都要遇到的工作。变量是计算机内存中已命名的存储位置,在大部分的语言中都有很多种类的变量,如整数型、浮点型和字符串等,不同的变量有不同的用途和尺寸,比如说虽然长整数和单精度浮点数都是32位长,但它们的用途不同。
顾名思义,变量的值在程序运行中是需要改变的,所以它必须定义在可写的段内,如 .data和 .data?,或者在堆栈内。按照定义的位置不同,MASM中的变量也分为全局变量和局部变量两种。
详细地~~~~~
标号:标号(LABEL)是为一组机器指令所起名字.标号可有可无,只有当需要用符号地址来访问该语句时,才给此语句赋予标号.标号是程序目标标志,总是和某地址相联系,供转移或循环指令控制转移使用.
1 标号属性
因标号表示是指令地址,所以它有三个属性,即段属性、偏移属性和类型属性.段属性即段地址,标号段必须在CS中.偏移属性是表示该标号到段首地址距离,单位是字节,是16位无符号整数.类型属性是距离属性,指标号和转移指令距离,该标号在本段内引用,距离在-128~ 127之间时称短标号,距离属性为SHORT,当标号在本段,距离在-32768~ 32767之间时称近标号,距离属性为NEAR,当引用标号指令和标号不在同一段时称远标号,距离属性为FAR.
2 标号定义
标号定义有三种方法:
(1) 隐含说明标号距离属性为SHORT和NEAR标号可以使用隐含说明,即在代码段中定义,标识符后加冒号,放在一条汇编指令操作符前面.例:
NEXT: MOV AX,BX
----------
LOOP NEXT
- - - - - - - - - 
NEXT1: CMP AX,BX
JA NEXT1
其中NEXT和NEXT1都是标号名.
(2) 用LABEL定义标号
对于属性为NEAR和FAR标号均可以用这种定义.格式是:
标号名 LABEL NEAR/FAR
例如:NEXT LABEL NEAR/FAR
- - - - - - - - - 
LOOP NEXT
(3) 用EQU定义标号
对于属性为NEAR和FAR标号也可用EQU定义.格式是:
标号名 EQU THIS NEAT/FAR
例如:
NEXT EQU THIS NEAR
- - - - - - - - - 
LOOP NEXT
3 标号使用
(1) 无条件转移指令中标号作为转移地址
格式:
JMP 标号
其中标号可以是短标号,近标号或远标号
(2) 循环指令中,标号作为转移地址
格式:LOOP 标号
其中标号只能是短标号
(3) 条件转移中标号作为转移地址
格式:
条件转移指令 标号
其中标号只能用短标号
(4) 属性分离符
取段地址算符SEG
例如:MOV AX,SEG NEXT
SEG NEXT 就是取标号NEXT所在段段地址.
取偏移量算符OFFSET
例如:MOV BX, OFFSET NEX
其中OFFSET NEXT就是取标号NEXT有效地址,该语句等效于:LEA BX, NEXT
取类型算符TYPE
例如:
MOV AX, TYPE NEXT
若NEXT为近标号,则TYPE NEXT值为FFFFH(-1),若NEXT为远标号TYPE NEXT值为FFFEH(-2).其中-1和-2无真正物理意义,仅以数值表示标号类型而已.
变量:变量(Variable)代表存放在某些存储单元数据,这些数据在程序运行期间可以随时被修改.变量是通过变量名在程序中引用,变量名实际上是存储区中一个数据区名字,以变量名数据方式供程序员使用,作为指令或伪.指令操作数,大大方便了程序设计者.
由于变量是在逻辑段中定义.这就决定了变量和标号一样具有段属性、偏移属性和类型属性,前两个和标号属性相同,而类型属性是指出数据区数据项存取单位是字节(BYTE),字(WORD)或数字(DWORD)等.可见变量和标号主要区别在于变量指是数据,而标号则对应是指令
(1) 变量定义
变量通常也有三种定义法
用伪指令DB,DW,DD等来定义
格式:[变量名] 定义数据伪指令〈表达式〉
其中变量名可有可无,若没有名字则该变量为无名变量.表达式可以是常数、保留符号"?"、ASCII码字符串(只能用DB定义)、地址表达式(不能用DB定义)、预置数据表格和用DUP定义重复值.变量名可在任一逻辑段中定义,其后边不紧跟冒号而是加一空格
.例如:A DB 100;A为一个字节,值为100.
B DB 100,2 3;B值为100,B 1值为6.
C DB ‘ABC‘;C值为41H,C 1值为42H,C 2值为43H.D DB ?;
D是一个字节,预留一个字节,可以置入任何内容.
E DB 23 DUP(0);定义23个0,每一个0占一个字节.
F DB 3 DUP(1,2 DUP(0));定义9个数,顺序为:1,0,0,1,0,0,1,0,0.
G DW ‘AB‘,‘CD‘;G值为4142H,G 2值为4344H.
H DW 2 3;H为一个字,存放顺序为06,00H
I DW ? 预留一个字,占两个字节单元,
用伪指令LABEL定义变量
格式:
变量名 LABEL BYTE/WORD/DWORD
例如:
BUF LABEL BYTE
DB 21
它等价于 BUF DB 21
用伪指令EQU定义变量
格式:变量名 EQU THIS BYTE/WORD/DWORD
THIS是定义任意类型算符,它同LABEL一样用于建立变量或标号类型属性,而其段属性为语句所在段段地址,偏移属性为所在位置下一个能分配到可用偏移地址.例如:
STACK SEGMENT
DW 100 DUP(?
TOP EQU THIS WORD(或TOP LABEL WORD)
STACK END
变量TOP被定义为字类型,它偏移量应为STACK段定义100个字后下一个字偏移量,它恰就是堆栈指针SP初值,因此经常用这种方法为SP赋初值.
双重定义变量名利用隐含方式和显示方式双重方式,可以对同一位置定义为双重变量.
格式
〈变量名〉 EQU THIS〈类型〉
〈变量名〉 DB/DW/DD…
例如:
AB EQU THIS BYTE
(或AB LABEL BYTE)
AW DW 50 DUP(0)AW定义为字变量,在AW前使用了THIS BYTE,定义了一个字节类型变量,访问同一个位置,用AB按字节访问,用AW则按字访问.
(2) 变量访问
变量名作为存储单元直接地址
变量名用直接寻址时,变量类型必须与指令要求相符合.
例如:AB已定义字节变量,AW定义为字变量,用变量名作直接寻址形式如下:
MOV AH,AB
MOV AX,AW
用合成运算符PTR临时改变变量类型
接上例用
MOV CX,WORD PTR AB
MOV CL,BYTE PTR AW
则可临时把AB变为字类型,AW变为字节类型,但段和偏移属性不变.
变量名作为相对寻址中偏移量
例如:
MOV AX,AB〔SI〕
MOV AX,AW[BX][SI]
在这里AB,AW分别表示它们偏移量而不是它们所表示数据,常用于数组或表格操作中,AB[SI]就表示AB数组中第SI个元素.
属性分离符
其中SEG和OFFSET用法和标号相同,分别表示取变量所在段段地址和变量偏移地址.而TYPE运算符,将回送该变量类型所表示字节数.
例如:设AB为字节变量,AW为字变量,则:
MOV AH,TYPE AB即MOV AH,1
MOV AX,TYPE AW即MOV AX,2
取变量数据项个数运算符LENGTH对于变量定义时使用DUP情况,汇编程序将回送DUP前重复次数,即分配给该变量单元数,若表达式有多个DUP,则取第一个DUP项,其它情况则回送1.
例如:ARRAY DW 50 DUP(0)则
MOV CX,LENGTH ARRAY即MOV CX,50
ARRAY1,DW1,2,3 则
MOV CX,LENGTH ARRAY1
即MOV CX,1
可见LENGTH表示数组元素个数,而不管其类型.
取变量数据项长度算符SIZE
SIZE算符,汇编程序将回送分配给该变量字节数,即
SIZE=LENGTH TYPE
例如:
ARRAY DW 50 DUP(0) 则
SIZE ARRAY=50 2=100
要注意:对字符串变量求其长度,使用SIZE不能达到目.
例如:
ST DB ‘ABCDEFG‘ 则
SIZE ST值为1而不是7,欲求字符串长可用COUNT EQU $-ST,则COUNT值为7,其中$为定义ST一串字符后下一个可用偏移地址.
3 2 7 变量名仅对应数据区第一个数据项
例如:
WORD DW 20 DUP(?)
MOV AX,WORD;第一个元素送AX,
MOV AX,WORD 38;第20个元素送AX.

标号是指令的符号地址,标号出现在代码段中 变量是操作数的符号地址,变量一般出现在数据段中 
时间: 2024-12-29 23:49:14

汇编中标号与变量名的区别的相关文章

汇编中标号不加:的情况分析

对于汇编中标号不加:,如a db db a,b,c 等 标号都视为偏移地址,和转移指令地址的差不同,用标号时(除转移)就等于其偏移地址,安装时需要注意这个.

ASP中轻松实现变量名-值变换

用过PHP的朋友都知道,PHP中变量的使用灵活方便,特别是能在字符串中方便实现变量名-值变换,使得整个PHP代码更显简洁优美.比如一条更新数据库的SQL语句只需写成:"update users set password='$password', group=$group, name='$username' where account='$account'",其中的$password.$group.$username.$account便会被实际的变量值替换,而在ASP中要实现相同的功能必

解决ambiguous symbol命名空间中类名、变量名冲突的问题

最近在将一个复杂的工程集成到现有的项目中.编译时发现,有的变量名冲突了,提示就是xxxx ambiguous symbol,并且在编译输出时,指明了两个文件当中特定的变量名或者类名相同.出现这个编译错误的原因是,在工程中加载了两个头文件,这两个头文件中包含相同的类名或者变量名,解决及避免出现此类错误的方法如下: 代码库尽量包含在一个命名空间中.在我们写一个大的程序时,一些变量可能会与其他工程造成重名,所以加命名空间是很有必要的:另外,在自己的代码库中命名的类名变量名尽量以代码库的名称开头,这样大

c#中@开头的变量名

在 C#  规范中, @  可以作为标识符(类名.变量名.方法名等)的第一个字符,以允许C# 中保留关键字作为自己定义的标识符.如 class @class { public static void @static(bool @bool) { if (@bool) System.Console.WriteLine("true"); else System.Console.WriteLine("false"); } } class Class1 { static vo

js中,var 修饰变量名和不修饰的区别

js中 允许在定义变量的时候 不加var 修饰符.js会在当前作用域下寻找上下文是否定义了此变量, 如果没有找到则会为这个变量分配内存.当且将其视为window的成员. 也就是全局变量. 如果加了var 修饰符. js会重新为这个变量分配内存,不论当前上下文中是否已经定义过了.这个变量的作用域就为当前上下文. 即局部变量. 不加var的写法是强烈不推荐的.1. 语义不清楚. 2. 团队开发时,容易覆盖掉其它作用域内的变量,引发异常.3. 给window对象添加不必要成员. 等等

机器学习中常用的变量名

batchsize:中文翻译为批大小(批尺寸).在深度学习中,一般采用SGD训练,即每次训练在训练集中取batchsize个样本训练: iteration:中文翻译为迭代,1个iteration等于使用batchsize个样本训练一次:一个迭代 = 一个正向通过+一个反向通过 epoch:迭代次数,1个epoch等于使用训练集中的全部样本训练一次:一个epoch = 所有训练样本的一个正向传递和一个反向传递 原文地址:https://www.cnblogs.com/keyshaw/p/11031

shell语法—shell 中特殊的变量名

现在我们新建一个demo1.sh 脚本文件,代码如图 chomd +x demo1.sh   给脚本执行权限. 我们在命令行输入 让我们来看下执行的结果 大家可以自己写一个脚本执行 试试,有什么问题,欢迎大家指出,让我们共同进步!

c语言变量名和地址的关系

在汇编编译器编译时直接将变量名转换成内存地址,变量名并不占内存空间 在编译的时候编译器会把程序中出现的所有变量名都换成相对内存地址,变量名不占内存 变量名不占空间 变量:用来标识(identify)一块内存区域,这块区域的值一般是可以更改的,这就是它"变"的由来,但是我们可以通过使用如const等一些修饰符号来限定这一内存区域的操作特性(characteristic),即变量的操作特性.用const修饰的使变量不能更改的就和常量一样的变量叫做常变量. 变量名:是一个标识符(identi

python 变量名解析 LEGB原则

对于一个def语句: 变量名分为三个作用域进行查找:首先是本地,之后是函数内,之后是全局,最后是内置 在默认的情况下,变量名赋值会创建或者改变本地变量 当函数中使用未认证的变量名时,Python就会搜索4个作用域(本地作用域,之后是上一层结   构中def或lambda的本地作用域,之后是全局作用域,最后是内置作用域, 但函数中给一个变量名赋值时,Python总是创建或者改变本地作用域的变量名,除非它已经在那个函数中声明为 全局变量 当在函数之外给一个变量名赋值时(也就是一个模块文件的顶层)本地