1. equ指令
equ指令(英文为:equal),在Nasm汇编器中是一条伪指令。我们知道伪指令不能直接执行,需要经过编译器处理转换成纯汇编指令。类似equ指令的语法,在很多编程语言中都存在,有的叫做定义常量,比如我们学习C语言会接触到一个#define的语法,跟equ指令的作用是一样的,因为equ指令的本质就是替换。
直接上代码吧:
mov ax,100
mov bx,100
mov cx,100
times 510-($-$$) db 0x00
dw 0xAA55
上述代码中,依次将寄存器ax,bx,cx的值都修改为100了。考虑这么一种情况,如果我们要把寄存器的值全部修改为200的话就很不方便,这仅仅是3个数据,如果是30或300,甚至更多的数据呢?在这种情况下,使用equ伪指令显然就简单多了。
使用equ指令修改代码:
num equ 110
mov ax,num
mov bx,num
mov cx,num
times 510-($-$$) db 0x00
dw 0xAA55
编译之后如下图所示:
伪指令编译之后就消失了,同时会把num替换成立即数110(十六进制为0x6E),所以这就是个替换的过程。
equ指令声明的任何数字是不占用内存的,因为它是一个立即数,是直接从指令中得到,而不是要从内存中寻址得到这个数。另外通过equ指令给立即数赋值有意义的名称,还可以提高代码的可读性和可维护性。
2. jmp指令的各种写法
jmp指令是一个跳转指令,通过下面的代码我们来看一下jmp指令的跳转过程:
Mark:
mov ax,0x1111 ;3
mov bx,0x2222 ;6
mov cx,0x3333 ;9
jmp near Mark ;12
首先我们知道其实地址是0x07c00,以上三条指令各自占用3个字节,而jmp指令也占用3个字节,所以当执行jmp指令时,就会计算与标号Mark的距离,然后减去12,回到Mark标号的位置(即起始地址0x07c00)处开始执行了。
在jmp指令中,near是附近的意思。但是jmp near指令不修改CS寄存器,只影响IP寄存器,通知IP寄存器增加,或者减去一个固定数值: 16位的有符号数。
near因为不修改段寄存器,只影响IP寄存器,所以通常把jmp near叫做段内转移,因为它只在一个段内转移。
还有一种写法:
jmp 0x0000:0x7C00 ;这种写法是直接修改cs和ip寄存器
这种写法不叫段内转移。