无法使用'&' Gnu AS 表达式中的运算符
我想获取变量的地址并按 4096 编辑(这将对应于其内存页的地址)。因为这是可以离线计算的东西,所以我做了一些看起来像这样的事情(v是变量,vpage应该包含其页面的地址):
.data
v: .zero 0x100
vpage: .long v & 0xfffff000
尝试使用x86汇编器编译此文件会导致以下错误:
test.S: Assembler messages:
test.S:3: Error: invalid sections for operation on `v' and `L0'
Why would GAS拒绝计算这个?现在奇怪的部分:替换“&”通过“+”,代码将编译,链接后甚至可以正确计算地址。任何有关此行为原因或如何解决此问题的提示都将非常受欢迎。
I would like to get the address of a variable and'ed by 4096 (which would correspond to the address of its memory page). Since this is something that can be computed offline I did something that looks like this (v is the variable and vpage should contain the address of its page):
.data
v: .zero 0x100
vpage: .long v & 0xfffff000
Trying to compile this file with the x86 assembler results in the following error:
test.S: Assembler messages:
test.S:3: Error: invalid sections for operation on `v' and `L0'
Why would GAS refuse to compute this? Now the weird part: replace '&' by "+" and the code will compile and the address will even be correctly computed after link. Any hint on the why of this behavior or how to fix it would be very welcome.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
问题是 GAS 生成将由链接器处理的目标文件。虽然 GAS 确实支持按位 AND 运算,但它不能对绝对地址执行此操作。它们可能会被链接器更改,因此 GAS 必须生成仅支持有限操作(主要是偏移)的重定位条目。如果您可以将绝对地址转换为(本地)相对地址,GAS 可以在组装时计算它。否则,您将必须在运行时通过代码来完成此操作。
The problem with this is that GAS generates object files that will be processed by the linker(s). While GAS does support bitwise AND operation, it can not do so with absolute addresses. They are subject to change by the linker, and hence GAS must generate relocation entries that only support limited operations (mainly just offsetting). If you can turn your absolute address into (local) relative address GAS can compute it during assembly time. Otherwise, you will have to do it from code at runtime.
在英特尔语法中,您可以使用
_AND
、_OR
、_NOT
、_SHL
、_SHR
也许还有其他人可以实现这一目标。这也可能适用于 GNU 的汇编器。In Intel syntax you can use
_AND
,_OR
,_NOT
,_SHL
,_SHR
and maybe others to accomplish this. This might work in GNU's assembler as well.