64 bit assembler > UASM Assembler Development

jwasm 2.10 vs jwasm 2.11 ~ uasm 2.38 problem

(1/3) > >>

fonolite:
Hello~

I have some problems in between jwasm 2.10 and jwasm 2.11 ~ uasm 2.38.
Here is my code.

mov edi, fs:[var]   ; inside USE64 64bit segment  (long mode) & omf object.
[var] = static varable in data segment
assume DS:FLAT , FS:_DATA , bla bla bla

No.1) jwasm 2.10 : mov edi, fs:[var] => mov edi, fs:[var]

No.2) jwasm 2.11 ~ uasm 2.38 : mov edi, fs:[var] => mov edi, fs:[var+eip]  (showed in runtime debugger like bochs)

You know fs & gs are used for relative offset like 16bit or 32bit segment.

I want to continue to use the No.1 way with uasm 2.38 for new cpu instructions.

Please help me for solving this problems.

habran:
There is no difference between ml.exe and uasm.exe, they produce the same code but they break because system uses GS and FS for its purpose, here are code:
ml.exe:

--- Code: ---009A1067 64 8B 3D 00 50 9A 00 mov         edi,dword ptr fs:[9A5000h] 
    57:     mov eax, [edi]
009A106E 8B 07                mov         eax,dword ptr [edi] 

--- End code ---
UASM:

--- Code: ---    56:     mov edi, [fs:var]
01331057 64 8B 3D 00 50 33 01 mov         edi,dword ptr fs:[1335000h] 
    57:     mov eax, [edi]

--- End code ---
in 32 bit you can still access data with LEA EDI and then use MOV EAX[EDI]
however, in 64 bit FS contents is garbage and brakes the code

this is from intel Introduction to x64 Assembly.pdf

--- Quote --- Indirect: this allows using an 8, 16, or 32 bit displacement, any general purpose registers for base and index, and a scale of 1, 2, 4, or 8 to multiply the index. Technically, these can also be prefixed with segment FS: or GS: but this is rarely required.
MOV R8W, 1234[8*RAX+RCX] ; move word at address 8*RAX+RCX+1234 into R8W There are many legal ways to write this. The following are equivalent
MOV ECX, dword ptr table[RBX][RDI]
MOV ECX, dword ptr table[RDI][RBX]
MOV ECX, dword ptr table[RBX+RDI]
MOV ECX, dword ptr [table+RBX+RDI]
The dword ptr tells the assembler how to encode the MOV instruction.
 RIP-relative addressing: this is new for x64 and allows accessing data tables and such in the code
relative to the current instruction pointer, making position independent code easier to implement.
MOV AL, [RIP] ; RIP points to the next instruction aka NOP NOP
Unfortunately, MASM does not allow this form of opcode, but other assemblers like

--- End quote ---
UASM supports RIP relative encoding

fonolite:
First of all, thanks for your kind answer.

I googled rip-relative addressing these days.

1) I found yasm (maybe nasm has the same grammers.) has rel & abs specifiers for symbols.
https://www.tortall.net/projects/yasm/manual/html/nasm-effaddr.html
http://www.nasm.us/doc/nasmdoc6.html#section-6.2.1
3.3.2. RIP Relative Addressing
mov [rel sym], rax  ; RIP-relative
mov [abs sym], rax  ; not RIP-relative
mov [fs:sym], rbx   ; not RIP-relative (fs or gs use)
I think the 3rd ([fs:sym]) means exactly what I want for the special purpose of FS & GS 's segment relative offset in 64bit segments.

2) Intel ASM386 has the similar directives.
https://archive.org/stream/bitsavers_inteliRMXi9165003ASM386AssemblyLanguageReference19_1663542/469165-003_ASM386_Assembly_Language_Reference_1995_djvu.txt
Relative Displacement Directives
Syntax
RELB fparam
RELW fparam
or
RELD fparam
Where:
fparam is the name of a formal parameter with a C (code) specifier letter.
Discussion
The relative displacement directives instruct the assembler to generate the
displacement between the end of an instruction and a label expression operand as
follows:



Does uasm/jwasm/wasm have the similar expression for the specific absolute addressing only for FS & GS segments?

johnsa:
We don't have any rel/abs type addressing modifiers at present, something I've been thinking about.
Immediately however as a fix for 2.42 I would suggest that NO fs/gs reference should ever be rip relative.
If everyone is ok with that that should be easy to do.

Edit: Possibly ANY segment override should force this behaviour?

so
mov eax,[rdi]   ; this would allow RIP relative and be rip relative where possible
mov eax,seg:[rdi]   ; non-RIP

fonolite:
Thanks, johnsa

I analyzed the full sources of uasm and debugged them with visual studio.
And I found the changing point of parser.c about fs segment between jwasm v2.10 and v2.11.

I built the v2.40 newest uasm's modified sources with visual studio and it makes fs:[var] have no rip-relative offset.
So I'll use this program temporarily.

If uasm v2.42+ will have no rip-relative offset with segment override only for FS & GS segments, I'll appreciate that.


4) parser.c
v2.11+
#if AMD64_SUPPORT
            /* v2.03: the non-RIP encoding for 64bit uses a redundant SIB mode (base=none, index=none) */
            /* v2.11: always use 64-bit non-RIP addressing if no fixup has been created. */
            //if ( CodeInfo->Ofssize == USE64 && CodeInfo->prefix.RegOverride != EMPTY && SegOverride != &ModuleInfo.flat_grp->sym ) {
            if ( CodeInfo->Ofssize == USE64 && CodeInfo->opnd[CurrOpnd].InsFixup == NULL ) {
                DebugMsg1(( "set_rm_sib: 64-bit, no fixup, data64=%" I64_SPEC "X\n", CodeInfo->opnd[CurrOpnd].data64 ));
                rm_field = RM_SIB;
                CodeInfo->sib = 0x25; /* IIIBBB, base=101b, index=100b */
            }
#endif

=> from v2.10
#if AMD64_SUPPORT
            /* v2.03: the non-RIP encoding for 64bit uses a redundant SIB
             * mode (base=none, index=none) */
            if ( CodeInfo->Ofssize == USE64 &&
                CodeInfo->prefix.RegOverride != EMPTY &&
                SegOverride != &ModuleInfo.flat_grp->sym ) {
                DebugMsg1(( "set_rm_sib: 64-bit non-RIP direct addressing: SegOverride=%X, flat=%X\n", SegOverride, ModuleInfo.flat_grp ));
                rm_field = RM_SIB;
                CodeInfo->sib = 0x25; /* IIIBBB, base=101b, index=100b */
            }
#endif

Navigation

[0] Message Index

[#] Next page

Go to full version