The MASM Forum

General => The Laboratory => Topic started by: jj2007 on August 29, 2015, 08:03:11 PM

Title: ALIGN 64
Post by: jj2007 on August 29, 2015, 08:03:11 PM
Any idea how to achieve align 64? I've tried with currentpos=$ etc but no success so far.
Title: Re: ALIGN 64
Post by: dedndave on August 29, 2015, 09:48:51 PM
you might try a macro that generates 0's until the address mod 64 = 0
Title: Re: ALIGN 64
Post by: dedndave on August 29, 2015, 09:50:37 PM
start with ALIGN 16 - generate 0's in 16-byte blocks   :P
Title: Re: ALIGN 64
Post by: nidud on August 29, 2015, 10:22:02 PM
deleted
Title: Re: ALIGN 64
Post by: jj2007 on August 29, 2015, 10:29:37 PM
Looks good, Nidud :t

JWasm inserts the right amount of bytes, but ML 6.15 and ML 10 choke, after a long while, with "fatal error A1004: out of memory". Even better, ML 10 drives one of my cores to 100%. Naive Windows user might think that is no problem for a multitasking OS, but it slows down the whole system to a crawl, and the only solution is to reboot (and it takes ages to shut it down in this freeze condition...). Windows 7-64 at its best 8)

include \masm32\include\masm32rt.inc
Align64 MACRO
Local pos
  pos=0 ; PROBLEM: how to get initial position
  ; pos=$ ; not possible
  WHILE 1
pos=pos+1
ife (pos and 63)
EXITM
endif
nop
  ENDM
ENDM

alignx macro x
while (($ - _TEXT) and (x - 1))
   nop
   align 16
endm
endm

.code
start:
nop
codeStart:
  ; Align64
  alignx 64
codeEnd:

  mov eax, codeEnd
  sub eax, codeStart
  inkey str$(eax), " bytes inserted"
  exit
end start
Title: Re: ALIGN 64
Post by: dedndave on August 29, 2015, 10:45:47 PM
Quote from: nidud on August 29, 2015, 10:22:02 PM

alignx macro x
while (($ - _TEXT) and (x - 1))
   nop
   align 16
endm
endm


you can't emit NOP's in the data section
try it with DB 0
Title: Re: ALIGN 64
Post by: jj2007 on August 29, 2015, 10:51:12 PM
Quote from: dedndave on August 29, 2015, 10:45:47 PMyou can't emit NOP's in the data section

It's supposed to be in the code section, Dave:

include \masm32\include\masm32rt.inc
alignx macro x
  while (($ - _TEXT) and (x - 1))
nop
align 16
  endm
endm

.code
start:
  nops 20 ; misalign for testing
codeStart:
  alignx 64
codeEnd:

  mov ebx, start
  print hex$(ebx), " is start:", 13, 10
  mov ebx, codeStart
  print hex$(ebx), " is codeStart:", 13, 10
  mov ebx, codeEnd
  print hex$(ebx), " is codeEnd:", 13, 10
  mov eax, ebx
  sub eax, codeStart
  inkey str$(eax), " bytes inserted"
  exit
end start


Output:
00401000 is start:
00401014 is codeStart:
00401040 is codeEnd:
44 bytes inserted

Title: Re: ALIGN 64
Post by: nidud on August 29, 2015, 11:04:00 PM
deleted
Title: Re: ALIGN 64
Post by: nidud on August 29, 2015, 11:27:08 PM
deleted
Title: Re: ALIGN 64
Post by: jj2007 on August 30, 2015, 12:03:25 AM
Nidud,
Your macro works perfectly with JWasm, see reply #6, but it hangs with ML...
Title: Re: ALIGN 64
Post by: TouEnMasm on August 30, 2015, 12:58:12 AM

And what about LINK  /ALIGN:64 ??
Seems the more secure way.
Title: Re: ALIGN 64
Post by: nidud on August 30, 2015, 01:05:59 AM
deleted
Title: Re: ALIGN 64
Post by: jj2007 on August 30, 2015, 03:43:06 AM
Fails with ml 6.15 :(

But here is one tested with ML 6.15 + 10.0 and JWasm:

include \masm32\include\masm32rt.inc

AlignX macro abytes
Local xbytes
  xbytes=abytes-(($-_TEXT) and (abytes-1))
  if xbytes
db xbytes dup(90h)
  endif
endm

.code
start:
nops 20 ; misalign for testing
codeStart:
  AlignX 64
codeEnd:

  mov ebx, offset start
  print hex$(ebx), " is start:", 13, 10
  mov ebx, offset codeStart
  print hex$(ebx), " is codeStart:", 13, 10
  mov ebx, offset codeEnd
  print hex$(ebx), " is codeEnd:", 13, 10
  mov eax, ebx
  sub eax, codeStart
  inkey str$(eax), " bytes inserted"
  exit
end start


Thanks a lot for the inspiration, Nidud :t

And here is a first application (timings welcome, see attached exe):

      NanoTimer()
      AlignX 64
      .Repeat
            inc swVar
            .If swVar > MaxVar
                  xor swVar, swVar
            .EndIf
            MbSwitch_s:
            Switch_ swVar      ; --------- new MasmBasic macro, ~40% faster ------------
            Case_ 5
                  inc ct0
            Case_ 1
                  inc ct1
            Case_ 2
                  inc ct2
            Case_ 3
                  inc ct3
            Case_ 4
                  inc ct4
            Default_
                  inc ctDef
            Endsw_

            MbSwitch_endp:
            inc loopCt
      .Until loopCt >= Loops
      Print Str$("%i\tms for MasmBasic Switch\t", NanoTimer(ms)), Str$("ct1=%i", ct1), Str$(", ct2=%i", ct2), Str$(", ct3=%i", ct3), Str$(", ctDef=%i\n", ctDef)


Intel(R) Core(TM) i5-2450M CPU @ 2.50GHz
1083    ms for plain if chain   ct1=10000000, ct2=10000000, ct3=10000000, ctDef=150000000
1055    ms for if/elseif chain  ct1=10000000, ct2=10000000, ct3=10000000, ctDef=150000000
1086    ms for Masm32 switch    ct1=10000000, ct2=10000000, ct3=10000000, ctDef=150000000
607     ms for MasmBasic Switch ct1=10000000, ct2=10000000, ct3=10000000, ctDef=150000000

1055    ms for plain if chain   ct1=10000000, ct2=10000000, ct3=10000000, ctDef=150000000
1027    ms for if/elseif chain  ct1=10000000, ct2=10000000, ct3=10000000, ctDef=150000000
1093    ms for Masm32 switch    ct1=10000000, ct2=10000000, ct3=10000000, ctDef=150000000
615     ms for MasmBasic Switch ct1=10000000, ct2=10000000, ct3=10000000, ctDef=150000000

1031    ms for plain if chain   ct1=10000000, ct2=10000000, ct3=10000000, ctDef=150000000
1036    ms for if/elseif chain  ct1=10000000, ct2=10000000, ct3=10000000, ctDef=150000000
1072    ms for Masm32 switch    ct1=10000000, ct2=10000000, ct3=10000000, ctDef=150000000
596     ms for MasmBasic Switch ct1=10000000, ct2=10000000, ct3=10000000, ctDef=150000000

52      bytes for PlainIf
52      bytes for ElseIf
54      bytes for SwitchMasm32
84      bytes for MbSwitch
Title: Re: ALIGN 64
Post by: hutch-- on August 30, 2015, 04:35:23 AM
i think from memory that you can set the code alignment in an object module to values higher than 16. With the tool FDA in MASM32 which produces a data object module and I think from memory it works the same way with a code module.
Title: Re: ALIGN 64
Post by: nidud on August 30, 2015, 04:52:57 AM
deleted
Title: Re: ALIGN 64
Post by: nidud on August 30, 2015, 05:50:17 AM
deleted
Title: Re: ALIGN 64
Post by: jj2007 on August 30, 2015, 06:53:40 AM
Quote from: nidud on August 30, 2015, 04:52:57 AM
What happened with version 6.15, how did it fail?

It inserts zeros:
00401013                  ³.  90                     nop
00401014                  ³.  0000                   add [eax], al
00401016                  ³.  0000                   add [eax], al


Strange, now that I tested it again it fails with all assemblers, with an exception. Copied and pasted from your code above...
alignx macro x
if (($ - _TEXT) and (x - 1))
    org $ + x - (($ - _TEXT) and (x - 1))
endif
endm


What do you see in the debugger with this code?
.code
start:
nops 19 ; misalign for testing
int 3
codeStart:
  alignx 64
codeEnd:

Title: Re: ALIGN 64
Post by: nidud on August 30, 2015, 07:38:17 AM
deleted
Title: Re: ALIGN 64
Post by: jj2007 on August 30, 2015, 10:45:03 AM
Quote from: nidud on August 30, 2015, 07:38:17 AMKeep in mind that the $ offset is zero based so you cant use this approach in a library or object module.

Very good point :t

I've included Align64 in the latest MasmBasic edition of 30 August (http://masm32.com/board/index.php?topic=94.0). It will throw an error when used in a library:

include \masm32\include\masm32rt.inc
AlignX macro abytes
Local xbytes
  ifndef start
.err <### AlignX can't be used in libraries and object modules ###>
  endif
  xbytes=abytes-(($-_TEXT) and (abytes-1))
  if xbytes
db xbytes dup(90h)
  endif
endm
Align64 equ <AlignX 64>

.code
start:
nops 20 ; misalign for testing
codeStart:
  Align64
codeEnd:

  mov ebx, offset start
  print hex$(ebx), " is start:", 13, 10
  mov ebx, offset codeStart
  print hex$(ebx), " is codeStart:", 13, 10
  mov ebx, offset codeEnd
  print hex$(ebx), " is codeEnd:", 13, 10
  mov eax, ebx
  sub eax, codeStart
  print str$(eax), " bytes inserted"
  exit
end start


Output:
00401000 is start:
00401014 is codeStart:
00401040 is codeEnd:
44 bytes inserted