当前行被汇编后的地址

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了当前行被汇编后的地址相关的知识,希望对你有一定的参考价值。

nasm中,$是当前行被汇编后的地址,我想问这个地址是如何确定的?
按照楼下几位的说法,$是当前段的指令的偏移地址,那么$$岂不是恒等于0,但事实上$$却不是如此,我想搞清楚这一点是为了更好地了解实模式与保护模式之间段偏移的差别

$表示当前偏移地址,也就是它所在的位置。举例说明,定义数据段及数据如下:
Data Segment
Buff db 'Welcome to you.'
N equ $-Buff
Data Ends
因为变量Buff占12个字节,$的当前地址就是12(就是它的偏移量),相应的常量N的值也是12。

又如,定义代码段:
Code Segment
Start:
mov ax,7
inc al
jmp $+7
mov bx,100h
add bx,ax
mov ah,4ch
int 21h
Code Ends
End Start
这里$的值是5,因为它前面的两条指令
mov ax,7
inc al
占5个字节
第3条指令jmp $+7意指跳转到距当前位置7个字节的位置,即跳转到指令mov ah,4ch处执行。

补充回答:
$单独使用,表示当前偏移地址;若是连着使用,如$$、$$$等,就不是表示当前偏移地址了,而只是一个普通的标识符了,这个很关键。
参考技术A 我觉得你问的问题不是很明确。不过nasm是一个宏汇编器。
$就是一个宏。
他会在第一次扫描之后尝试展开。
也就是说nasm首先对你的代码编译一次,把能够编译的先编译。
此时剩下$等符号,然后从头开始替换掉。

可以这样理解
源程序:
.....
mov ax,$+7
.....
第一次扫描后
.....
xxxx: mov ax,7
.....
第二次扫描后
.....
xxxx: mov ax,7+xxxx ->完成
....

当然有些情况很复杂,比如jz之类的指令它的长度一次扫描可能不能确定,那可能会进行多次扫描。实际情况很复杂,我就简明介绍一下。如果看不懂可以提问。
参考技术B

我来说两句;

其实你知道当前程序地址意义不是特别大,非要看的话,你可以打开反汇编窗口,看前面的地址就知了(见附图:51的反汇编窗口);如果你用跳转指令的话,直接用标志符简单多了,而且出错的机率也少;很多单片机一条指令会占两个或三个字节的flash空间。

参考技术C $$,$只有汇编的时候起作用,$是全局的地址计数器,娄遇到一个声明段的伪指令时,$$并不清零,而是将$中的值赋给$$ 参考技术D 在开始的地方设置或者默认(没有设置的话)一个地址(应该可以默认吧,不设置编译一下试试)(编译器改置一个变量记录)。然后逐句编译汇编指令(把指令长度加到这个变量上)。直到$行,这时候这个变量的值就是当前行汇编后的地址。 第5个回答  2009-09-19 这个地址是根据你前面有多少指令,每条指令的长度相加算出来的

8086汇编 jcxz 指令

8086汇编 jcxz 指令

指令格式:jcxz 标号
功能:如果(cx)=0,则转移到标号处执行当(cx)≠0时,什么也不做(程序向下执行)

  • 当(cx)=0时,(IP)=(IP)+8位位移)
  • 8位位移=“标号”处的地址-jcxz指令后的第一个字节的地址;
  • 8位位移的范围为-128~127,用补码表示;
  • 8位位移由编译程序在编译时算出。

jcxz是有条件转移指令

  • 所有的有条件转移指令都是短转移
  • 对IP的修改范围都为-128~127
  • 在对应的机器码中包含转移的位移,而不是目的地址

注:当cs等于0 、jcxz转移到 ok 。

案例

assume cs: codesg
codesg segment
start: mov ax, 2000H
    mov ds, ax
    mov bx
s: mov cx, [bx]
    jcxz ok
    inc bx
    inc bx
    jmp short s
ok: mov dx, bx
    mov ax, 4c00H
    int 21H
codesg ends
end start

 

以上是关于当前行被汇编后的地址的主要内容,如果未能解决你的问题,请参考以下文章

汇编数据段地址问题 看我的源代码,从反汇编的代码中可以看到段地址DS应该为075A 但是D命令查看的结果不是

汇编call的问题

关于汇编的段内转移

汇编指令JMP是啥意思?

汇编指令JMP是啥意思?

arm汇编b指令是绝对地址还是相对地址跳转?