请解释一下字符串中的 m4 嵌套定义

问题描述 投票:0回答:2

我目前正在阅读《SPARC架构、汇编语言编程和C.第二版》这本书。我到了书中的某个地方,我不明白或无法理解某个命令:

 define(loc, 0)
 define(sto, 'loc:  44 $1 define('loc', eval(loc+2))')

问题是,我确实理解第一行。但我真的不明白第二行的第二个参数。书上的解释也没有帮助。

摘自书中:

这里我们首先定义了一个符号 loc,其值为 0。该符号将代表位置计数器,即正在汇编的指令的内存地址。每个宏定义都已更改,首先打印 loc 的当前值,然后将 loc 重新定义为 loc 加上存储指令所需的内存位置。

宏的参数是字符和字符串,而不是数值。在重新定义 loc 的值时,我们使用另一个内置宏 eval。 eval 使用其字符串参数来表示算术表达式。 eval 计算该表达式并以数字字符串的形式返回其值。

我知道上述解释对您来说可能听起来很清楚,但对我来说却不然。我完全不明白的是这部分: 'loc: 44 $1 Define('loc', eval(loc+2))'

我不明白:

为什么这是一个字符串?

为什么loc必须在那里?

为什么定义了 44 $1 后,还有另一个定义,“define('loc', eval(loc+2))'?

assembly macros processor m4
2个回答
3
投票

听起来任务是使用 m4 宏制作汇编程序。预期的输出将类似于:

0000: 44 xx
0002: yy zz
...

也就是说,每一行都以地址为前缀,后跟机器代码字节。

开头的

loc:
将为您打印当前地址,
44
可能是
sto
指令的操作码,
$1
是参数。最后一部分是重新定义
loc
,使其指向下一个可用位置。由于该指令占用两个字节,因此
loc
增加2。

请注意,m4 使用反引号来启动字符串。您可能从书中抄错了。

鉴于此示例输入:

define(loc, 0)
define(sto, `loc:  44 $1 define(`loc', eval(loc+2))')
sto(01)
sto(AA)

输出为:

0:  44 01
2:  44 AA

0
投票

在理解m4时,你必须顽固地遵循m4所遵循的逻辑。

阅读

define(loc, 0)

这是一个宏,不会展开任何内容。接下来有一个新行,并且该新行仍然存在。然后它评估参数。 m4 查找loc幸运的是它还没有定义。如果是例如

define(loc, 0)

define(loc, 12)

然后第二个宏将在扩展后执行

define(0, 12)

并且loc的值仍然是0。 通常你应该转义你想要定义的宏的名称,所以

define(`loc', 0)

define(`loc', 12)

现在loc的展开确实是12。 (这应该会让你对本书作者的知识渊博感到厌倦。)

现在是第二行(已更正)

 define(`sto', 'loc:  44 $1 define('loc', eval(loc+2))')

M4评估参数

sto 
loc:  44 $1 define('loc', eval(loc+2))

显然 sto 将成为一个宏。 define(st.. 扩展为仅一个空行。

现在看看 sto 的用法,例如使用参数 orangutan 来调用它。

sto(`orangutan')  

然后 m4 扩展 sto

0: 44 orangutan define(`loc', eval(0+2))

Pigheadely 将 loc 替换为 0,只要它没有转义。 该定义扩展为空,但具有给 loc 值 2 的效果。 因此,第二行扩展(具有 loc 的副作用)到

0: 44 orangutan 
© www.soinside.com 2019 - 2024. All rights reserved.