【问题标题】:Defining a debugging macro in assembly (with gas?)在汇编中定义调试宏(使用气体?)
【发布时间】:2021-01-10 04:50:35
【问题描述】:

为了在调试器之外进行调试,我通常会添加基本的打印语句,例如:

    str: .string "Hello!\n"

    mov $1,     %rdi
    mov $str,   %rsi
    mov $7,     %rdx
    mov $1,     %eax
    syscall

有没有办法创建一个宏,我可以改为这样写:

print ($str, $7)

它会自动扩展为:

mov $1,     %rdi
mov $1,     %eax
mov $str,   %rsi
mov $7,     %rdx
syscall

我查看了macro 的gas 文档,但似乎它使用的语法我不确定它是在哪里定义的(似乎他们正在使用for 循环?)。是否可以在 asm 中执行上述操作?我想如果不是,我可以在 vim 中创建一个可以“扩展”到上述内容的 sn-p。


感谢您的建议。我用来打印上面的测试宏是:

.macro DEBUG str_addr, str_len
    mov $1,         %edi
    mov $\str_addr, %rsi
    mov $\str_len,  %edx
    mov $1,         %eax
    syscall
.endm

DEBUG str, 7

虽然语法有点奇怪,但对于“普通指令”(而不是循环或条件,例如),宏语法被称为:

macro arg1, arg2

并定义为:

.macro <macro_name> <arg1>, <arg2>, ...

.endm

变量名需要用\ 转义。因此,例如要引用arg1,您必须执行\arg1

【问题讨论】:

  • CPP 宏通常比 GAS 的原生宏更易于使用。如果你想要 () 围绕 args,你可能需要 CPP 风格的宏。我认为调用 GAS 宏使用的语法类似于 asm 指令 macroname arg, arg。如果您在 Google 上搜索 gas macro 并查看一些出现在 SO 问题中的示例,您可以看到这一点。
  • @PeterCordes 我明白了。宏在汇编中被认为是“不好的做法”,还是根本没有使用?
  • Asm 宏确实可以使用,它们只是不使用您要求的语法,所以我建议使用 CPP 宏。 GAS 宏在某些方面不如 NASM 方便,至少如果你想重复某事可变的次数,但这很简单。如果您仔细记住它破坏的寄存器是什么,调试打印宏可能是有意义的。 (您可能想要推送/弹出宏周围使用的所有寄存器,包括 RCX 和 R11)通常使用调试器来查看执行的位置很有效:与 C 不同,机器确实直接执行您的指令,因此调试器非常有用。
  • 另外,如果你不小心的话,asm 宏会让你的代码很容易膨胀。如果你只是天真地使用一堆宏,你就会失去在事物之间进行优化的机会。 (如果您不关心优化,那么用 asm 编写没有多大意义。)当然,调试打印宏不是问题;它们仅用于调试。

标签: assembly x86 gnu-assembler


【解决方案1】:

当然。你应该可以做这样的事情(我手边没有油,所以未经测试):

.macro myprint s, len
    mov $1,     %rdi
    mov $\s,    %rsi
    mov $\len,  %rdx
    mov $1,     %eax
    syscall
.endm

那么你可以这样称呼它:

 myprint str, 7

【讨论】:

  • 看起来不错,我测试过了,唯一的问题是参数需要用\进行转义(前置)。
  • @samuelbrody1249 - 请告诉我适合你的语法,我会相应地更新我的回复:)
  • 刚刚将其添加到问题中。
  • 是的,我可以将其称为DEBUG $str, $7,然后从宏中删除两个直接的$。但是一旦我删除了\,我就会收到一个汇编错误:(.text+0xb): undefined reference to str_addr'`。
  • 很公平 - 谢谢。我会更新我的帖子,并删除我无关的 cmets。
猜你喜欢
  • 2016-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-16
  • 1970-01-01
  • 2012-07-24
  • 1970-01-01
相关资源
最近更新 更多