为什么有时使用 offset flat:label 有时不用
why sometimes use offset flat:label and sometimes not
我正在使用英特尔语法使用 GNU 汇编器学习汇编,有人认为我不太了解。举例来说,这段代码就在这里:
.intel_syntax noprefix
.data
string: .asciz "hello world"
.text
.global entry
.type entry, @function
entry:
mov byte ptr[string + 4], 'a'
mov eax, offset flat:string
ret
我想到使用 offset flat: 因为我们正在编写可重定位代码。但是为什么我们不在他的行中也指定 offset flat:string
: mov byte ptr[string + 4], 'a'
就像我们在这里所做的那样 mov eax, offset flat:string
?
我真的很困惑。如果执行 mov byte ptr[string + 4], 'a'
可以获取 string 标签的地址 + 4 那么为什么执行 mov eax, string
不一样?
编辑:
澄清一下,在调用 entry 之后,我使用 printf 打印 EAX 中的内容,如下所示:
#include <stdio.h>
extern char *entry(void);
int main(int argc, char*argv[])
{
printf("%s", entry());
}
当你想要一个符号地址作为立即数时,你总是需要 OFFSET,比如 AT&T 语法 $string
而不是 string
。其他任何时候都不需要它。
基本上归结为这样一个事实,即在 GAS Intel 语法中(如 AT&T movb $'a', string+4
),string
即使没有 []
也是一个内存操作数,因此它需要额外的语法来询问地址而不是该地址的内存。
当使用 string
作为 [string + 4]
的一部分时,您不是在请求偏移量,而是在 label/symbol 地址寻址内存。将其用作寻址模式的一部分。
如果您更愿意使用 better-designed 语法,其中 mov eax, string+4
确实为您提供了地址(无需取消引用),请使用 NASM.
否则请参阅 Confusing brackets in MASM32(GAS 的 Intel 语法在大多数方面都类似于 MASM,只是 mov eax, [12]
是从该绝对地址加载的,而不是 MASM 的等价于 [=19 的疯狂=]),
并且有些相关: 关于 GAS 如何解析常量,但更多的是关于 .equ foo, 4
/ foo = 4
出现在引用它的指令之前和之后,如果您使用 mov eax, foo
而不是明确的 mov eax, [foo]
或 mov eax, OFFSET foo
还有:
我正在使用英特尔语法使用 GNU 汇编器学习汇编,有人认为我不太了解。举例来说,这段代码就在这里:
.intel_syntax noprefix
.data
string: .asciz "hello world"
.text
.global entry
.type entry, @function
entry:
mov byte ptr[string + 4], 'a'
mov eax, offset flat:string
ret
我想到使用 offset flat: 因为我们正在编写可重定位代码。但是为什么我们不在他的行中也指定 offset flat:string
: mov byte ptr[string + 4], 'a'
就像我们在这里所做的那样 mov eax, offset flat:string
?
我真的很困惑。如果执行 mov byte ptr[string + 4], 'a'
可以获取 string 标签的地址 + 4 那么为什么执行 mov eax, string
不一样?
编辑:
澄清一下,在调用 entry 之后,我使用 printf 打印 EAX 中的内容,如下所示:
#include <stdio.h>
extern char *entry(void);
int main(int argc, char*argv[])
{
printf("%s", entry());
}
当你想要一个符号地址作为立即数时,你总是需要 OFFSET,比如 AT&T 语法 $string
而不是 string
。其他任何时候都不需要它。
基本上归结为这样一个事实,即在 GAS Intel 语法中(如 AT&T movb $'a', string+4
),string
即使没有 []
也是一个内存操作数,因此它需要额外的语法来询问地址而不是该地址的内存。
当使用 string
作为 [string + 4]
的一部分时,您不是在请求偏移量,而是在 label/symbol 地址寻址内存。将其用作寻址模式的一部分。
如果您更愿意使用 better-designed 语法,其中 mov eax, string+4
确实为您提供了地址(无需取消引用),请使用 NASM.
否则请参阅 Confusing brackets in MASM32(GAS 的 Intel 语法在大多数方面都类似于 MASM,只是 mov eax, [12]
是从该绝对地址加载的,而不是 MASM 的等价于 [=19 的疯狂=]),
并且有些相关:.equ foo, 4
/ foo = 4
出现在引用它的指令之前和之后,如果您使用 mov eax, foo
而不是明确的 mov eax, [foo]
或 mov eax, OFFSET foo
还有: