【问题标题】:Flat Assembler: How do I get the address of an label?Flat Assembler:如何获取标签的地址?
【发布时间】:2016-08-19 23:51:02
【问题描述】:

如何获取标签的地址?

我想在不添加额外代码的情况下获取平面汇编器中标签的地址

示例:

label1:  ;is at adress 0
db 1h,2h,3h,4h,5h  ;some data

label2: is at address 5 because label1 has 5 bytes of data

我可以将地址打印到控制台屏幕,但这会增加程序的大小并改变结果。

我知道只使用标签,但我想要原始地址号码。

【问题讨论】:

  • 使用调试器或类似objdump 的工具从符号表中获取地址。如果您不使用标签地址,则它们不会存储在符号表之外的任何位置(例如,作为跳转目标、加载/存储地址、立即操作数或作为数据(例如 .dd label2)。
  • 好的。还有时间修改我的第一条评论并删除现在已经过时的评论。注意label1label2之间有5个字节的数据会更准确;标签没有关联的大小(除非您使用 MASM 或 TASM,其中标签后面的 db/dw/dd 神奇地暗示了在内存操作数中使用该标签的指令的操作数大小)。
  • 总之,澄清一下,您不想将地址放入寄存器或程序内部的内存中,对吧?您希望它以某种方式打印在屏幕上,与运行程序分开?
  • 是的,这正是我想要的
  • 公开标签,生成目标文件而不是可执行文件,使用链接器创建可执行文件并让链接器生成映射文件。该地图文件会告诉您标签的地址。

标签: assembly x86 fasm


【解决方案1】:

快速解决方案:

我只是将所有符号放在程序集文件的最后,然后用十六进制编辑器查看它:

示例:

label1: ;example label (can be anywhere)
;...
;... My Programm
;...

;the end of the program
db 0h ;just some spacer
dw label1

【讨论】:

  • 是的,这很有效,不应该干扰以前代码的布局。如果 FASM 有一个 ALIGN 指令,这可以使地址块很容易找到,并在十六进制转储输出行的开头对齐。您可能从我的回答中可以看出,我对 FASM 一无所知,并且主要在 Linux 上使用 NASM/YASM。
【解决方案2】:

使用调试符号构建程序,因此目标文件中的符号表(元数据)包含所有标签的地址。

然后您可以使用objdump -t 转储可执行文件或任何其他执行相同操作的程序的符号表。


除了符号表,标签地址将在二进制中嵌入指令中,例如在绝对寻址模式中用于寻址模式、立即操作数或作为数据(例如.dd label2)。正常跳转使用相对编码,所以在跳转的指令编码中找不到绝对符号地址。

TL:DR:反汇编二进制文件以找到绝对地址是可能的,但仅限于以这种方式使用的标签,因此符号表更方便。


如果您正在组装平面二进制文件(如引导扇区),则文件格式中没有符号表。因此,当您使用命令行选项执行此操作时,您依赖于为您提供 FASM 打印符号信息。我google了一下,发现there's a -s option写了一个.fas符号信息调试输出文件。

【讨论】:

  • 我不确定 FASM 是否支持调试符号,很遗憾,.fas 文件不是人类可读的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-20
  • 1970-01-01
  • 1970-01-01
  • 2021-11-14
相关资源
最近更新 更多