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
Code: [Select]
alignx macro x
while (($ - _TEXT) and (x - 1))
   nop
   align 16
endm
endm
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)

Code: [Select]
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
Code: [Select]
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
you can't emit NOP's in the data section

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

Code: [Select]
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:
Code: [Select]
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
you can't emit NOP's in the data section

 :P

Code: [Select]
00000000 .data
00000000  90 nop
00000000 .code
00000000  90 nop
Title: Re: ALIGN 64
Post by: nidud on August 29, 2015, 11:27:08 PM
Code: [Select]
.486
.model flat
alignx macro x
while (($ - _TEXT) and (x - 1))
   nop
   align 16
endm
endm
.data
nop
alignx 64
nop
.code
bar label byte
end

Code: [Select]
                                .data
00000000  90                    nop
                                alignx 64
00000040  90                    nop
00000000                        .code
00000000                        bar label byte
                                end

Segments and Groups:
FLAT . . . . . . . . . . . . . .        GROUP
_DATA  . . . . . . . . . . . . .        32 Bit   00000041 Para    Public  'DATA'
_TEXT  . . . . . . . . . . . . .        32 Bit   00000000 Para    Public  'CODE'
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
Code: [Select]
alignx macro x
if (($ - _TEXT) and (x - 1))
    org $ + x - (($ - _TEXT) and (x - 1))
endif
endm
EDIT: if not aligned..
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:

Code: [Select]
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)


Code: [Select]
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
The object alignment is always zero and the linker normally align 16, but this will not help if you want to align a specific label in a given segment other than offset 0.

I tested version 6.11, 6.14, and 9.00 and they seems to work fine.
What happened with version 6.15, how did it fail?

Title: Re: ALIGN 64
Post by: nidud on August 30, 2015, 05:50:17 AM
Come to think of it you actually HAVE to align all objects (at least the ones you use the macro in) to 64 from the top for this to work.
Title: Re: ALIGN 64
Post by: jj2007 on August 30, 2015, 06:53:40 AM
What happened with version 6.15, how did it fail?

It inserts zeros:
Code: [Select]
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...
Code: [Select]
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: [Select]
.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
It inserts zeros:

Yes, they all should pad with zeros.

Quote
Strange, now that I tested it again it fails with all assemblers, with an exception.

As it should if you fall trough the ORG offset as you do. You have to pad with nop's in that case.

Quote
What do you see in the debugger with this code?

I didn't test real code, only viewed the list output. Keep in mind that the $ offset is zero based so you cant use this approach in a library or object module.
Title: Re: ALIGN 64
Post by: jj2007 on August 30, 2015, 10:45:03 AM
Keep 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:

Code: [Select]
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:
Code: [Select]
00401000 is start:
00401014 is codeStart:
00401040 is codeEnd:
44 bytes inserted