Author Topic: jwasm 2.10 vs jwasm 2.11 ~ uasm 2.38 problem  (Read 280 times)

fonolite

  • Regular Member
  • *
  • Posts: 5
jwasm 2.10 vs jwasm 2.11 ~ uasm 2.38 problem
« on: September 02, 2017, 06:10:37 PM »
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

  • Member
  • *****
  • Posts: 1107
    • uasm
Re: jwasm 2.10 vs jwasm 2.11 ~ uasm 2.38 problem
« Reply #1 on: September 02, 2017, 10:40:17 PM »
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: [Select]
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] 
UASM:
Code: [Select]
    56:     mov edi, [fs:var]
01331057 64 8B 3D 00 50 33 01 mov         edi,dword ptr fs:[1335000h] 
    57:     mov eax, [edi]
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
UASM supports RIP relative encoding

Cod-Father

fonolite

  • Regular Member
  • *
  • Posts: 5
Re: jwasm 2.10 vs jwasm 2.11 ~ uasm 2.38 problem
« Reply #2 on: October 12, 2017, 12:06:04 PM »
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

  • Member
  • ****
  • Posts: 520
    • Uasm
Re: jwasm 2.10 vs jwasm 2.11 ~ uasm 2.38 problem
« Reply #3 on: October 12, 2017, 11:20:47 PM »
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

« Last Edit: October 13, 2017, 03:12:18 AM by johnsa »

fonolite

  • Regular Member
  • *
  • Posts: 5
Re: jwasm 2.10 vs jwasm 2.11 ~ uasm 2.38 problem
« Reply #4 on: October 13, 2017, 01:47:58 PM »
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
« Last Edit: October 14, 2017, 12:14:16 PM by fonolite »

johnsa

  • Member
  • ****
  • Posts: 520
    • Uasm
Re: jwasm 2.10 vs jwasm 2.11 ~ uasm 2.38 problem
« Reply #5 on: October 13, 2017, 08:17:35 PM »
It will be so in 2.42 coming soon to a store near you :)

fonolite

  • Regular Member
  • *
  • Posts: 5
Re: jwasm 2.10 vs jwasm 2.11 ~ uasm 2.38 problem
« Reply #6 on: October 14, 2017, 12:07:59 PM »
My sources including fs:[var] work fine with uasm 2.42 now.

Thank you so much johnsa.

nidud

  • Member
  • *****
  • Posts: 1370
    • https://github.com/nidud/asmc
Re: jwasm 2.10 vs jwasm 2.11 ~ uasm 2.38 problem
« Reply #7 on: October 15, 2017, 04:43:28 AM »
I made this test case from the description above
Code: [Select]
ifdef __JWASM__
_TEXT segment PARA FLAT PUBLIC 'CODE'
_TEXT ends
_DATA segment PARA FLAT PUBLIC 'DATA'
_DATA ends
assume cs:flat,ds:flat,ss:flat,es:flat,fs:_DATA,gs:nothing
endif

_DATA segment
var dd 1
_DATA ends

_TEXT segment
lea rcx,gs:[1234h]
lea rax,var
lea rdx,fs:[var]
lea eax,var
lea edx,fs:[var]
mov edi,fs:[var]
_TEXT ends

    end

The output from ml64 and (now) asmc:
Code: [Select]
; Note: Address is not rip-relative
; Note: Absolute memory address without relocation
        lea     rcx, DS:[1234H]                         ; 0000 _ 48: 8D. 0C 25, 00001234
        lea     rax, [var]                              ; 0008 _ 48: 8D. 05, 00000000(rel)
        lea     rdx, [var]                              ; 000F _ 48: 8D. 15, 00000000(rel)
        lea     eax, [var]                              ; 0016 _ 8D. 05, 00000000(rel)
        lea     edx, [var]                              ; 001C _ 8D. 15, 00000000(rel)
ASSUME  fs:flat
        mov     edi, dword ptr fs:[var]                 ; 0022 _ 64: 8B. 3D, 00000000(rel)

Output from uasm:
Code: [Select]
        lea     rcx, [?_001]                            ; 0000 _ 48: 8D. 0D, 00001234(rel)
        lea     rax, [var]                              ; 0007 _ 48: 8D. 05, 00000000(rel)
; Note: Unusual relocation type for this operand
        lea     rdx, DS:[var+$+7H]                      ; 000E _ 48: 8D. 15, 00000000(d)
        lea     eax, [var]                              ; 0015 _ 8D. 05, 00000000(rel)
; Note: Unusual relocation type for this operand
        lea     edx, DS:[var+$+6H]                      ; 001B _ 8D. 15, 00000000(d)
; Note: Address is not rip-relative
ASSUME  fs:flat
        mov     edi, dword ptr fs:[var]                 ; 0021 _ 64: 8B. 3C 25, 00000000(d)

Apparently this never worked correctly. I added these changes to parser.c:
Code: [Select]
    rm_field = RM_D32; /* D32=101b */
    if ( CodeInfo->Ofssize == USE64 ) {
if ( CodeInfo->opnd[CurrOpnd].InsFixup == NULL ) {
    rm_field = RM_SIB;    /* 64-bit non-RIP direct addressing */
    CodeInfo->sib = 0x25; /* IIIBBB, base=101b, index=100b */
} else if ( CodeInfo->opnd[CurrOpnd].InsFixup->type == FIX_OFF32 ) {
    /* added v2.26 */
    CodeInfo->opnd[CurrOpnd].InsFixup->type = FIX_RELOFF32;
                }
    }

habran

  • Member
  • *****
  • Posts: 1107
    • uasm
Re: jwasm 2.10 vs jwasm 2.11 ~ uasm 2.38 problem
« Reply #8 on: October 15, 2017, 08:22:14 AM »
Hi nidud, that is nice solution :t
Now this is what we get with UASM:
Code: [Select]
   219: assume cs:flat,ds:flat,ss:flat,es:flat,fs:_DATA,gs:nothing
   220: lea rcx,gs:[1234h]
00007ff7353910e5 48 8D 0C 25 34 12 00 00          lea rcx, ptr [0x1234] 
   221: lea rax,var
00007ff7353910ed 48 8D 05 40 3F 00 00             lea rax, ptr [rip+0x3f40] 
   222: lea rdx,fs:[var]
00007ff7353910f4 48 8D 15 39 3F 00 00             lea rdx, ptr [rip+0x3f39] 
   223: lea eax,var
00007ff7353910fb 8D 05 33 3F 00 00                lea eax, ptr [rip+0x3f33] 
   224: lea edx,fs:[var]
00007ff735391101 8D 15 2D 3F 00 00                lea edx, ptr [rip+0x3f2d] 
   225: mov edi,fs:[var]
00007ff735391107 64 8B 3D 26 3F 00 00             mov edi, dword ptr fs:[rip+0x3f26] 

Cod-Father

johnsa

  • Member
  • ****
  • Posts: 520
    • Uasm
Re: jwasm 2.10 vs jwasm 2.11 ~ uasm 2.38 problem
« Reply #9 on: October 16, 2017, 12:42:05 AM »
why does it still say rip in the disasm ?