汇编语言学习07:参数,变量和符号

目录

数值型(常参)常数和表达式

常数

表达式

变量定义伪指令

初值表初始化

类型伪指令

定位伪指令

变量和标号属性符号

地址操作符

类型操作符


上一章主要提到了汇编语言的各种指令,但是根据对高级语言的认知来看,每条指令需要传递变量或者参数。本节就来讲述参数、变量和符号。

数值型(常参)常数和表达式

数值型参数包含常数和表达式。其中,常数是一个固定的数值,而表达式间接给出了一个数值。

常数

常数的定义比较广泛,通常分为以下几种:

  • 十进制常数:由0~9组成,以字母D/d结尾或者省略结尾(这是因为汇编语言对大小写不敏感)。例如: 34d 或者34表示十进制常数34,在内存中表达为22。
  • 十六进制常数:和DOS表达的内存数值进制形式相同,以字母H/h结尾。如果是以字母开头的十六进制数,还需要在最前面加0,避免与其他符号混淆。例如:无符号数64H表示十进制常数100,0FFH表示十进制常数255
  • 二进制常数:以字母B/b结尾。例如01101100B。
  • 八进制常数:以字母Q/q结尾。比如144Q。
  • 字符串常数:缩略号括起来的单个或者多个字符。
  • 符号常数:利用标识符表达的一个数值。可以使用符号名替代上面四种以及表达式来简化程序,提高可读性。类似于C语言的#define。其基本格式如下:
    name EQU constant
    name EQU <string>
    name = expression
    

由上可以看出,汇编语言区分进制是靠后置字符(B,Q,D,H)区分的。省略后缀时,默认为十进制。当然,在实际使用时,可以使用.RADIX指令改变默认进制。

表达式

汇编语言一样允许传递数值确定的表达式。表达式中允许含有以下运算符:

  • 算术运算符+,-,*,/,MOD
  • 逻辑运算符AND,OR,XOR,NOT
  • 移位运算符SHL,SHR
  • 关系运算符EQ,GT,LT,GE,LE
  • 高低分离符HIGH,LOW,HIGHWORD,LOWWORD。这是单目运算符,操作数必须是符号常量。不能是一般常数
  • MASM规定的一些其他运算符。根据MASM手册的规定决定。

总而言之,汇编语言许多常量的定义和后面出现的高级语言如出一辙,但是汇编语言里面某些位的操作符变得更加常用。

变量定义伪指令

变量定于伪指令为便改良申请固定长度的存储空间,并且可以同时进行初始化。该类伪指令是最常使用的伪指令之一。其基本格式为:

name cmd init ;变量名 伪指令 初值表
初值表初始化

初值表初始化一般用逗号分别参数,可以是数值常数,表达式或者‘?’,‘DUP’组成。其中‘?’表示不初始化,‘DUP’表示重复初始化,下面给出DUP的格式和例子。

重复次数 DUP (重复参数)
array DB 10 DUP (0)    ;array初始化为10个字节,每个字节都是0组成的数组
类型伪指令

定义变量时可以分配新的内存单元供变量存储。类型伪指令包含DB,DW,DD,DF,DQ,DT等指令,各个指令的基本格式如下:

DB    ;定义字节单元define byte,可以定义多个单元,每个单元占1字节
DW    ;定义字单元define word,同上
DD    ;定义双字单元define double word,同上
DF    ;定义三字伪指令,通常表示48位远指针
DQ    ;定义四字伪指令,通常表示64位整数long long
DT    ;定义10字节伪指令

 从MASM6.0开始,上述指令被建议改为BYTE,WORD,DWORD,FWORD,QWORD,TBYTE。

定位伪指令

除了类型伪指令之外,还可以定义数据或者指针所在的偏移地址,利用现有的存储单元。定位伪指令包含ORG,EVEN和ALIGN指令。这三个指令的基本格式如下:

ORG 0100H   ;从100H开始安排数据或者程序
ORG $+10    ;偏移地址加10,其中$表示当前的偏移地址
EVEN        ;使得当前的偏移地址指针指向偶数地址。若已经偶数不变化,否则跳跃到下一个偶数地址。一般可以用于对齐字量数据。
ALIGN  N    ;使得当前的偏移地址指针指向模N地址。变化规则和EVEN相同。一般对齐2的乘方(2,4,8,16,……)

这些指令也可以在代码段中使用,和JMP类似。 

变量和标号属性符号

变量和标号一般具有两种属性:地址属性和类型属性。其中,地址属性表示对应存储单元的逻辑地址,一般包含段地址和偏移地址。类型属性对应段内或者段间,数据单元类型等等。

地址操作符

我们先前已经见到一些地址操作符,例如[ ]表示取地址操作符,$表示当前的偏移地址,:表示段前缀操作符。此外还有一些经常应用的地址操作符:

OFFSET 名字/标号    ;返回名字或者标号的偏移地址
SEG 名字/标号       ;返回名字或者标号的段地址

OFFSET是一个非常常用的指令,之前在实验中遇到过OFFSET取得字符串的偏移地址输出字符串的实例,OFFSET还常常用于代码段指令中,使用OFFSET DONE-OFFSET START(START和DONE对应主程序中某段指令开头结尾)来得到主程序的以字节为单位的长度。

类型操作符

类型操作符包含PTR指令,THIS指令和TYPE指令,还包括MASM定义的其他属性操作符,包括SIZEOF和LENGTHOF操作指令。

ptr指令在8086数据传送指令中已经见过,一般用法是使得两个操作数的存储类型对齐。例子如下:

MOV AL, byte ptr [BX+SI]    ;[bx+si]可能是字单元数据,在此被转换为字节数据,只传低字节。

this指令说明操作数具有汇编时的当前逻辑地址,但是就具有指定的类型,类型名和ptr操作符中的类型一样。如下是一个例子:

b_var equ this byte ;按字节访问b_var,但是和变量w_var地址相同

 除此之外,MASM中还提供了一个LABEL伪指令,其功能等同于equ this。

type指令返回一个字量值,表明名字或者标号占据的字节空间量。

常数0
结构每个结构占据的字节数
变量该变量数据占据的字节数
标号距离属性值,根据短转,近转和远转分别为FF01,FF02和FF05
寄存器该寄存器所具有的字节数,r8是1,r16 是2

复习:在128字节内的转移属于短转移;同段内128字节外的转移属于近转移;段间属于远转移

关于更详细的关于属性的应用,请参见XMU汇编语言实验04.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是一个汇编语言和C语言混合编程实例,它将使用C语言编写一个简单的函数,并在汇编语言中调用该函数: ```c #include <stdio.h> int add(int a, int b) { return a + b; } int main() { int a = 5; int b = 10; int c = add(a, b); printf("The sum of %d and %d is %d\n", a, b, c); return 0; } ``` 上面的代码定义了一个名为“add”的函数,该函数将两个整数相加并返回结果。在主函数中,我们声明了三个整数变量a、b和c,然后调用add函数来计算a和b的和,并将结果存储在c中。最后,我们使用printf函数将结果输出到控制台。 现在,我们将在汇编语言中调用add函数。为此,我们需要创建一个汇编文件,并使用汇编语言实现一个名为“call_add”的函数。该函数将把两个整数作为参数传递给add函数,并返回add函数的结果。 下面是一个示例汇编文件: ```assembly section .data a dd 5 b dd 10 section .text global _start _start: mov eax, [a] mov ebx, [b] push ebx push eax call add add esp, 8 mov [c], eax mov eax, 4 mov ebx, 1 mov ecx, message mov edx, message_len int 0x80 mov eax, 1 xor ebx, ebx int 0x80 section .data message db 'The sum of 5 and 10 is ', 0 message_len equ $-message section .bss c resd 1 extern add ``` 上面的代码首先声明了两个整数变量a和b,并将它们初始化为5和10。然后,我们定义了一个名为“call_add”的函数,在该函数中,我们将从a和b中读取值,并将它们作为add函数的参数传递。我们使用“push”指令将这些参数压入堆栈中,然后调用add函数。在返回之前,我们使用“add esp, 8”指令清除堆栈上的参数。最后,我们将add函数的返回值存储在名为“c”的变量中,并使用printf函数将结果输出到控制台。 在这个示例中,我们使用了“extern”指令来引用C语言中定义的add函数。这告诉链接器在链接时将add函数的地址解析为汇编代码中的符号。 要编译和链接这个示例程序,我们可以使用以下命令: ```bash gcc -c example.c nasm -f elf32 example.asm ld -m elf_i386 example.o example.o -o example ``` 上述命令将首先编译C语言源文件“example.c”,然后使用NASM汇编器将汇编文件“example.asm”编译为目标文件。最后,我们使用链接器将两个目标文件链接在一起,并生成一个名为“example”的可执行文件。 现在,我们可以运行这个程序,看看它是否能够正确地计算5和10的和,并将结果输出到控制台。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值