PrefaceI put this into here because i thought is an advanced topic 
(
probably not 
).
But have a look at this, is fun 
:

I already know that
offset is (in global variables contex) more efficient than
lea (both in speed and size). But i started to look for alternatives to this operator and, of course a didn't found (probably, you tell me if you know

) any other alternative more efficient than this inmediate value computed in assembly time and inserted in the instruction. So
offset seems to be the best for this cases.
What i found, however, was a very interesting thing:
.386
.model flat,stdcall
option casemap:none
.data
@@:
foo dword 20
pfoo dword foo
.code
start:
mov eax,foo ; The value.
mov eax,offset foo ; The address of foo.
mov eax,pfoo ; The address of foo.
mov eax,@b ; The address of foo.
end start
What i found interesting is that @@ will be the only label that will work for this (any other label name will give an assembly time error). You can try this code with a debugger.
And you can try this too (the .exe is attached):
.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
.data
@@:
foo db "wow!",0
.code
start:
push MB_OK
push @b
push @b
push 0
call MessageBox
push 0
call ExitProcess
end start
And of course it will work!
But if you use more than one @@: in your data section, from the code you will be referencing the same label always (of course) and not the others (i mean when you do something like jmp @b or jz @f, etc). So we can do this:
.386
.model flat,stdcall
option casemap:none
.data
@@:
foo dword 20
pfoo dword foo
ff dword 30
.code
start:
mov eax,foo ; The value.
mov eax,offset foo ; Address of foo.
mov eax,pfoo ; Address of foo.
mov esi,@b ; Address of foo.
add esi,8 ; Address of ff.
mov eax,[esi] ; The value (30) in eax.
end start
You can try that code with a debugger too.
So one more example of this (the .exe is attached):
.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
.data
@@:
tit db "hello",0
cont db "wow!",0
.code
start:
push MB_OK
mov esi,@b ; Address of the data section.
push esi ; First element's offset .
add esi,6 ; We want the next string.
push esi ; Second element's offset.
push 0
call MessageBox
push 0
call ExitProcess
end start
ConclusionSo yeah, this is (probably, you tell me if you know

) not as efficient as using the offset operator for global variables. But is fun!

Postface
