我从一篇课文中举了这样一个例子:
MOV R1, #7
LDR R2, = ioadr
STR R1, [R2]
ioadr .word 0x20001000
它说它会将值7存储到内存地址0x20001000。但是我想知道行LDR R2, = ioadr
。为什么我们不把ioadr的地址加载到R2?而是把值if ioadr加载到R2?汇编程序知道ioadr是常量而不是变量吗?难道不存在加载地址的情况吗?
PS:这个例子是用DCD,但据我所知,这相当于. word。
原始代码:
MOV R1, #7
LDR R2, = ioadr
STR R1, [R2]
ioadr DCD 0x20001000
1条答案
按热度按时间eagi6jfj1#
使用gnu汇编器进行arm。
这将失败,因为ioadr后面没有冒号
所以
这其中
是伪代码,1)不是所有的arm工具都支持,2)不是以同样的方式支持。它说你想把ioadr的地址加载到r2中。作为伪代码,你应该看到工具对它做了什么
未链接:
链接的
现在,您可以对照架构参考手册使用此函数,并轻松地看到它将ioadr的ADDRESS加载到r2中,而不是0x20001000
因此,当发生存储时,它会存储,并覆盖0x20001000,而不是写入0x20001000
将其更改为不同的伪代码,删除等号
现在它做了书中似乎在描述的事情。
加载操作将值0x20001000加载到r2中,以便存储操作实际上写入到0x20001000。
DCD和.word并不是您需要考虑的唯一汇编语言问题。正如您现在所看到的。如果您有任何问题,然后组装和拆卸,并先自己查找说明,然后如果仍然感到困惑,请将其与源代码沿着发布。
我怀疑这本书是错误的,这是另一个人生教训。文档是有缺陷的,假设它是,包括手臂文档。如果你有机会获得与书中汇编语言相匹配的手臂工具(如果这本书是半生不熟的,它会指定确切的工具和版本,我没有看),然后组装和拆卸。
正如您在本网站上看到的许多与ARM的等号伪代码相关的答案,例如
你会发现gnu会选择最佳的指令。(s)。但是其他工具,如果他们支持它的话,可能会照字面理解它,并使用一个字面池生成一个ldr。上面的第一个可能是来自一个字面池的pc相对负载,如上面基于您的代码的例子所示。后面的,使用gnu,将生成一个mov r1,#7而不是pc的相对负载。所以当使用这些东西的时候,小心使用。最重要的是要理解汇编语言是特定于工具的,而不是目标。有时候是工具的版本。同样,将c程序转换为java或python也需要工作,将汇编语言转换为arms工具也需要工作。(请注意,arm已经有了一系列的工具,重写或购买的小公司),以gnu binutils和回来。这是字面上的转换,从一个编程语言到另一个,只是没有那么苛刻的C到python。