News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

JWasm212pre reloaded

Started by habran, April 27, 2014, 11:57:41 AM

Previous topic - Next topic

habran

Hi everyone :biggrin:

I have here my version of JWasm212pre 8)
what is the difference? ::)
  1. built in .for - .endfor hll
  2. sophisticated RSP stack base for 64 bit   
  3. more compact stack usage
  4. first variable is always aligned to 16 byte
  5. if there is no invoke it will not allocate shadow space
  6. if there are no locals and no invoke there is no need to alocate the stack
 

to use 64 bit with this version you need to use 'option win64 : 11'  (eleven)

option casemap : none
option win64 : 11
option frame : auto
option stackbase : rsp


here are some examples to speak for themselves:


test1 PROC FRAME param : QWORD        ;this function has no locals but uses param
000000013FCE1060 48 89 4C 24 08       mov         qword ptr [param],rcx  ;param is saved 
  .if (param && rax == rcx)                            ;but no need to alocate the stack
000000013FCE1065 48 83 7C 24 08 00    cmp         qword ptr [param],0 
000000013FCE106B 74 0E                je          test1+1Bh (013FCE107Bh) 
000000013FCE106D 48 3B C1             cmp         rax,rcx 
000000013FCE1070 75 09                jne         test1+1Bh (013FCE107Bh) 
    mov rdx,1
000000013FCE1072 48 C7 C2 01 00 00 00 mov         rdx,1 
  .else
000000013FCE1079 EB 05                jmp         test1+20h (013FCE1080h) 
    mov rax,param
000000013FCE107B 48 8B 44 24 08       mov         rax,qword ptr [param] 
  .endif
ret
000000013FCE1080 C3                   ret 
test1 ENDP
;---------------------------------------------------------------------------------
test1 PROC FRAME param : QWORD       ;this function has no locals but uses rcx instead of param
.if (rcx && rax == rcx)              ;no need to save rcx in the shadow space
000000013FBC1060 48 23 C9             and         rcx,rcx 
000000013FBC1063 74 0E                je          test1+13h (013FBC1073h) 
000000013FBC1065 48 3B C1             cmp         rax,rcx 
000000013FBC1068 75 09                jne         test1+13h (013FBC1073h) 
    mov rdx,1
000000013FBC106A 48 C7 C2 01 00 00 00 mov         rdx,1 
.else
000000013FBC1071 EB 03                jmp         test1+16h (013FBC1076h) 
    mov rax,rcx
000000013FBC1073 48 8B C1             mov         rax,rcx 
.endif
ret
000000013FBC1076 C3                   ret 
test1 ENDP


this version has invoke in it:

test PROC  FRAME USES rbx rbp rdi   a : QWORD   
000000013FD81128 48 89 4C 24 08       mov         qword ptr [rsp+8],rcx   ;a param is used so it's saved
000000013FD8112D 48 89 5C 24 10       mov         qword ptr [rsp+10h],rbx ;store rbx in unused space
000000013FD81132 48 89 6C 24 18       mov         qword ptr [rsp+18h],rbp ;store rbp in unused space
000000013FD81137 57                   push        rdi ;even there is still free space push it for alignment
000000013FD81138 48 83 EC 60          sub         rsp,60h  ;40h for vars + 20h for shadows
LOCAL var    : XMMWORD                            ;16 byte vars at the beginning off locals
LOCAL var1   : XMMWORD                            ;are aligned to 16 byte
LOCAL other  : DWORD 
LOCAL other1 : QWORD     
LOCAL other2 : QWORD
LOCAL var2   : WORD   
LOCAL var3   : BYTE
    mov rax,-1
000000013FD8113C 48 C7 C0 FF FF FF FF mov         rax,0FFFFFFFFFFFFFFFFh 
    mov a,rax
000000013FD81143 48 89 44 24 70       mov         qword ptr [a],rax 
    invoke function,5                 
000000013FD81148 48 C7 C1 05 00 00 00 mov         rcx,5 
000000013FD8114F E8 0C FF FF FF       call        function (013FD81060h) 
    movaps var, xmm1             
000000013FD81154 0F 29 4C 24 20       movaps      xmmword ptr [var],xmm1 
    movaps var1, xmm2       
000000013FD81159 0F 29 54 24 30       movaps      xmmword ptr [var1],xmm2 
    mov other1, -1   
000000013FD8115E 48 C7 44 24 44 FF FF FF FF mov         qword ptr [other1],0FFFFFFFFFFFFFFFFh 
    mov other2, -2   
000000013FD81167 48 C7 44 24 50 FE FF FF FF mov         qword ptr [other2],0FFFFFFFFFFFFFFFEh 
    inc rax
000000013FD81170 48 FF C0             inc         rax 
    mov other2, rax
000000013FD81173 48 89 44 24 50       mov         qword ptr [other2],rax 
    inc rax 
000000013FD81178 48 FF C0             inc         rax 
    mov other2, rax
000000013FD8117B 48 89 44 24 50       mov         qword ptr [other2],rax 
    mov rax, 1111111h
000000013FD81180 48 C7 C0 11 11 11 01 mov         rax,1111111h 
    movd xmm1, rax
000000013FD81187 66 48 0F 6E C8       movd        xmm1,rax 
    shl rax, 1 
000000013FD8118C 48 D1 E0             shl         rax,1 
    .for (rax=rcx¦r8¦rcx++, r8--)
000000013FD8118F 48 8B C1             mov         rax,rcx 
000000013FD81192 4D 23 C0             and         r8,r8 
000000013FD81195 74 0A                je          test+79h (013FD811A1h) 
      mov[rcx], dl
000000013FD81197 88 11                mov         byte ptr [rcx],dl 
    .endfor
000000013FD81199 48 FF C1             inc         rcx  ;note how it uses INC here instead of ADD RCX,1
    .endfor
000000013FD8119C 49 FF C8             dec         r8  ;note how it uses DEC here instead of SUB r8,1
000000013FD8119F EB F1                jmp         test+6Ah (013FD81192h) 
    ret   
000000013FD811A1 48 83 C4 60          add         rsp,60h 
000000013FD811A5 5F                   pop         rdi 
000000013FD811A6 48 8B 5C 24 10       mov         rbx,qword ptr [rsp+10h] 
000000013FD811AB 48 8B 6C 24 18       mov         rbp,qword ptr [rsp+18h] 
000000013FD811B0 C3                   ret 
test ENDP


and the version without invoke:

test PROC  FRAME USES rbx rbp rdi   a : QWORD
000000013F4C1128 48 89 4C 24 08       mov         qword ptr [rsp+8],rcx 
000000013F4C112D 48 89 5C 24 10       mov         qword ptr [var1],rbx 
000000013F4C1132 48 89 6C 24 18       mov         qword ptr [rsp+18h],rbp 
000000013F4C1137 57                   push        rdi 
000000013F4C1138 48 83 EC 40          sub         rsp,40h  ;only space for locals alocated
LOCAL var    : XMMWORD                                     ;because no invoke calls
LOCAL var1   : XMMWORD
LOCAL other  : DWORD
LOCAL other1 : QWORD
LOCAL other2 : QWORD
LOCAL var2   : WORD
LOCAL var3   : BYTE
mov rax, -1
000000013F4C113C 48 C7 C0 FF FF FF FF mov         rax,0FFFFFFFFFFFFFFFFh 
mov a, rax
000000013F4C1143 48 89 44 24 50       mov         qword ptr [a],rax 
   ; invoke test1, 5
    movaps var, xmm1             
000000013F4C1148 0F 29 0C 24          movaps      xmmword ptr [rsp],xmm1 
    movaps var1, xmm2       
000000013F4C114C 0F 29 54 24 10       movaps      xmmword ptr [var1],xmm2 
    mov other1, -1   
000000013F4C1151 48 C7 44 24 24 FF FF FF FF mov         qword ptr [other1],0FFFFFFFFFFFFFFFFh 
    mov other2, -2   
000000013F4C115A 48 C7 44 24 30 FE FF FF FF mov         qword ptr [other2],0FFFFFFFFFFFFFFFEh 
    inc rax
000000013F4C1163 48 FF C0             inc         rax 
    mov other2, rax
000000013F4C1166 48 89 44 24 30       mov         qword ptr [other2],rax 
    inc rax 
000000013F4C116B 48 FF C0             inc         rax 
    mov other2, rax
000000013F4C116E 48 89 44 24 30       mov         qword ptr [other2],rax 
    mov rax, 1111111h
000000013F4C1173 48 C7 C0 11 11 11 01 mov         rax,1111111h 
    movd xmm1, rax
000000013F4C117A 66 48 0F 6E C8       movd        xmm1,rax 
    shl rax, 1 
000000013F4C117F 48 D1 E0             shl         rax,1 
    .for (rax=rcx¦r8¦rcx++, r8--)
000000013F4C1182 48 8B C1             mov         rax,rcx 
000000013F4C1185 4D 23 C0             and         r8,r8 
000000013F4C1188 74 0A                je          test+6Ch (013F4C1194h) 
      mov[rcx], dl
000000013F4C118A 88 11                mov         byte ptr [rcx],dl 
    .endfor
000000013F4C118C 48 FF C1             inc         rcx 
000000013F4C118F 49 FF C8             dec         r8 
    .endfor
000000013F4C1192 EB F1                jmp         test+5Dh (013F4C1185h) 
    ret   
000000013F4C1194 48 83 C4 40          add         rsp,40h 
000000013F4C1198 5F                   pop         rdi 
000000013F4C1199 48 8B 5C 24 10       mov         rbx,qword ptr [var1] 
000000013F4C119E 48 8B 6C 24 18       mov         rbp,qword ptr [rsp+18h] 
000000013F4C11A3 C3                   ret 
test ENDP


the folder contains JWasm binaries and MVS13 Expres solution
it also contains changed sources
because of forum limitation I couldn't upload complete sources
so if someone wants to build it, must download it from Japheth site and than add missing sources
headers are all there so you don't need to touch the H folder

here is the folder:

Cod-Father

habran

for people who are not familiar with .for - .endfor hll
can check here :biggrin:
Cod-Father

habran

To be able to build it with VC13 solution you'll have to do small changes to your path
From the menu chose Project->JWasm Property Pages
C/C++->General->Aditional Include Directories
and change the path from C:\Users\Hn\Desktop\JWasm2014 - OK\H
to your H folder ;)
Cod-Father

Adamanteus

Such line in macro, with REG stack variable gives result without and operation :
Code (asm) Select

if OPATTR (&REG) and 00000001b

habran

Hi Adamanteus
you should probably use:
  if OPATTR (REG)  :biggrin:
Cod-Father

Adamanteus

No - REG that's macro argument and need refference on what passed, than check if it constant by and operation.

habran

#6
the best thing is to try to assemble it with ml.exe
and see what will happen ;)
Cod-Father

habran

I have uploaded above a new version of JWasm with some fixes :biggrin:
the problem was in the flow of .for-.endfor hll
it was working fine if no .CONTINUE was used
because .CONTINUE is a jump to the start off the loop it would skip altering counters
I have redesigned it so that now increasing counters happens straight after the start
here is a simple example:

xstrlenA PROC FRAME wpString:PTR CHAR
xor rax,rax
  .if (rcx)
    .for (rax=rcx¦BYTE PTR[rax]¦rax++)
    .endfor
    sub rax,rcx
  .endif
  ret
xstrlenA ENDP
;;//----------------------------------------------------------------------
xstrlenA PROC FRAME wpString:PTR CHARxor rax,rax
000000013F884A30 48 33 C0             xor         rax,rax 
  .if (rcx)
000000013F884A33 48 23 C9             and         rcx,rcx 
000000013F884A36 74 12                je          xstrlenA+1Ah (013F884A4Ah) 
    .for (rax=rcx¦BYTE PTR[rax]¦rax++)
000000013F884A38 48 8B C1             mov         rax,rcx 
000000013F884A3B EB 03                jmp         xstrlenA+10h (013F884A40h) 
000000013F884A3D 48 FF C0             inc         rax 
000000013F884A40 80 38 00             cmp         byte ptr [rax],0 
000000013F884A43 74 02                je          xstrlenA+17h (013F884A47h) 
    .endfor
000000013F884A45 EB F6                jmp         xstrlenA+0Dh (013F884A3Dh) 
    sub rax,rcx
000000013F884A47 48 2B C1             sub         rax,rcx 
  .endif
  ret
000000013F884A4A C3                   ret
xstrlenA ENDP 
000000013F884A4B
Cod-Father

habran

#8
I have built JWasm.exe 64 bit with CodeBlocks 13.12 ussing GCC compiler
and was surprised how easy it imports MSVC solutions :icon_eek:
The CodeBlocks 13.12 actually works like a charm :t
only thing I had to do is to remove JWasm resource from the project
here it is:
Cod-Father

KeepingRealBusy

Quote from: habran on May 06, 2014, 06:24:43 PM
Ibecause .CONTINUE is a jump to the start off the loop it would skip altering counters
I have redesigned it so that now increasing counters happens straight after the start


Habran,

Won't that cause a different problem because the counters will represent the iteration to be executed next instead of the current iteration? If the counters are referenced inside of the "for" loop, then they would have the wrong value. The way to do this, IMHO, is to put the counter increment just in front of the loop start and jump to that for either a endfor or for a continue, and during initialization, jump around this increment code to go to the start point (or initialize the counters by decrementing them during initialization, and then just fall through to the increment code).

Dave.


habran

You are right Dave, that's what I have done but I expressed myself wrongly
I meant to say above the START label
thank you to point that out, that means that you have really given a thought about it

that also means that you can understand how advanced is this version of JWasm

it was a hard work to bring it to this level
however, I confess that I enjoyed it immensely :biggrin: 
Cod-Father

KeepingRealBusy

Habran,

If I had looked at the code itself, I would have seen this. I was just commenting on the explanation (I have never made a mistake  anything like that myself  :lol:).

Dave.

habran

Cod-Father

habran

I have uploaded a new file at the top with some improvements in  .for - .endfor hll
and a new feature in invoke macro
what I actually added is a change from 'move reg, 0' to 'xor reg,reg'

file: invoke.c
line:497

        else{
          /* v2.12 added by habran : if parametar  is zero use 'xor reg,reg' instead of 'mov reg,0' */
          if ((!strcmpi(paramvalue, "0") || (!strcmpi(paramvalue, "NULL")) || (!strcmpi(paramvalue, "FALSE"))))  {
            if (ms64_regs[index + base] > T_R9D) index -= 4;
            AddLineQueueX(" xor %r, %r", ms64_regs[index + base], ms64_regs[index + base]);
            return(1);
          }
          else
            AddLineQueueX(" mov %r, %s", ms64_regs[index + base], paramvalue);
        }
        *regs_used |= ( 1 << ( index + RPAR_START ) );
        DebugMsg1(("ms64_param(%s, param=%u): size=%u flags=%X\n", proc->sym.name, index, size, *regs_used ));
    }
    return( 1 );
}

as you can see I skipped checking if register is used so that we can use it again in the same call
other vise assembler would throw error that the register is already used
EG:
invoke testproc5, rdi,FALSE,NULL, 0,rdx, rdx

I would appreciate  a feedback

if in the first for params there are no zeros you can use ZERO MACRO posted in this forum
Cod-Father

Gunther

Hi habran,

Quote from: habran on August 27, 2014, 09:26:49 PM
I have uploaded a new file at the top with some improvements in  .for - .endfor hll
and a new feature in invoke macro
what I actually added is a change from 'move reg, 0' to 'xor reg,reg'

is it the current file under the first post?

Gunther
You have to know the facts before you can distort them.