关于NASM的列表中的括号
我正在尝试了解组装和链接的工作方式,因此我使用nasm生成了一个清单文件,并且我正在徘徊括号的含义([]),这是一种说明这是一个可能会在链接阶段?
编辑:我使用nasm -f obj
获得了此.LST文件
1 segment data public
2 00000000 4141414141414141 db 8 dup ('A')
3 segment code public
4 ..start:
5 00000000 B8[ssss] mov ax,data
6 00000003 B8[0300] mov ax,$
7 00000006 B8[0000] mov ax,..start
8 00000009 B80002 mov ax,200h
9 0000000C EBFE jmp $
I am trying to understand how assembling and linking work, so i have a listing file generated using NASM , and I am wandering about meaning of the brackets([]), it's a way to tell that this its a realocateble address that may change in the linking phase?
Edit:I am getting this .lst file using nasm -f obj
1 segment data public
2 00000000 4141414141414141 db 8 dup ('A')
3 segment code public
4 ..start:
5 00000000 B8[ssss] mov ax,data
6 00000003 B8[0300] mov ax,$
7 00000006 B8[0000] mov ax,..start
8 00000009 B80002 mov ax,200h
9 0000000C EBFE jmp $
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
NASM用方括号 [] 或括号()()在清单转储中装饰可重定位的值。这通常表明,括号中的值可能与链接程序中的值有所不同,该值可以在运行时在调试器中看到。
汇编器不知道如何是来自其他分别组装模块的代码和数据,在链接时间串联在一起。它都不知道在运行时加载代码和数据的地址,因此假设所有段都从地址 0 开始。绝对搬迁(由 [] 标记)指定括号(偏移)中的值需要增加以匹配运行时的最终地址。
在您的16bits示例中,仅当您的程序将与其他一些模块链接时,此差异仅适用,该模块还定义了
段代码public
public>,并且如果此其他模块首先进行,从而在您的code中提升了组装的偏移量。
段。否则,第6和7行的偏移在链接时间之后是有效的,这些说明将被编码为b80300
和b80000
在最终的可执行文件中(不会适用任何重新定位)。指令
JMPN
和calln
与以下指令的地址进行编码(在指令指针寄存器中保存),所谓的< strong> rip - 相关性解决。当近JMP
或使用同一段执行
时,汇编器能够立即计算差异,并且不请求搬迁。但是,我们也可以从其他单独组装模块调用一些过程。尽管此过程也可能位于段代码public
中,它将与主代码
segment链接在一起,但汇编程序不知道片段的最终布局,因此它必须花费相对重新安置请求,并用括号()在编码calln
中的直接值。第5行是另一种野兽:它编码
data> data
段的第一个字节的段地址 段,而不是其偏移。这就是为什么NASM在[sss]
而不是[0000]
中显示段落地址,并且该值肯定是零以外的 - 它取决于地址DOS将在其中加载dos可执行程序。用
MOV AX,DATA
,MOV DS,AX
的初始化段寄存器的初始化不是唯一需要段重新定位的情况,它用于编码每个JMPF
和callf
指令。jmpf
和callf
编码的远处的指针是在MZ标头之后的DOS可执行文件中收集的(所谓的 relipocation rocation )和它们被用于修改远处指令的部分部分,并在加载时间上存储了远处的指针。其他汇编者可能会在列出不同的列表中发出信号,
例如€asm 使用 [] ,() /strong>和 {} 以区分绝对,相关和分段 - 地址重新定位。
NASM decorates relocatable values in the listing dump with square brackets [ ] or with parenthesis ( ). This generally signalizes that the value in brackets may differ from the value in linked program, which can be seen in debugger at run-time.
Assembler does not know how will be code and data from other, separately assembled modules, concatenated together at link-time. Neither it cannot know the address where the code and data will be loaded at run-time, so it assumes that all segments start at address 0. Absolute relocation (marked by [ ]) specifies that the value in brackets (offset) requires increase to match the final address at run-time.
In your 16bits example this difference applies only if your program will be linked with some other module which also defines
segment code public
, and if this other module goes first, thus elevating assembled offsets in yourcode
segment. Otherwise offsets at lines 6 and 7 are valid after link-time and those instructions will be encoded asB80300
andB80000
in the final executable (no relocations will apply).Instructions
JMPN
andCALLN
encode the target address relative to the address of the following instruction (which is kept in instruction pointer register), so called RIP-relative addressing. When the NEARJMP
orCALL
is performed withing the same segment, assembler is able to calculate the difference immediately and no relocation is requested. However, we may also call some procedure from other, separately assembled module. Although this procedure might lie in thesegment code public
, too, which will be linked together with the maincode
segment, assembler doesn't know the final layout of segments, so it must expend relative relocation request, and decorates the immediate value in encoding ofCALLN
with parenthesis ( ).Line 5 is a different beast: it encodes segment address of the first byte of
data
segment rather than its offset. Thats why NASM displays the paragraph address with[ssss]
instead of[0000]
and this value will be definitely other than zero - it depends on the address where DOS will load the executable program.Initialization of segment registers with
mov ax,data
,mov ds,ax
is not the only case when segment relocation is necessary, it is used in encoding of everyJMPF
andCALLF
instruction. Far pointers to the segment part ofJMPF
andCALLF
encoding are gathered in DOS executable file right after the MZ header (so called relocation entries) and they are used to modify the segment part of FAR instructions and of stored FAR pointers at load-time.Other assemblers may signalize relocations in listing differently,
for instance €ASM uses [ ], ( ) and { } to distinguish absolute, RIP-relative and segment-address relocations.