Hi,
Packages are updated on the site as well as git.
Changes are:
Fixes:
1) Fixed usage text to show SSE as the default architecture.
2) Fixed 32bit addressing mode issue when using Array[n] (variable indexed by constant).
3) Minor RBP stack-frame fixes.
4) Fix for RSP stack setup using WIN64 < 11.
5) Fix for vmovupd addressing mode. This error was also affecting evex encoding instructions that can't use 1 byte displacement.
Improvements:
1) Updated and cleaned up the unix build.
2) Re-organized the samples folder and descriptions.
3) Adjusted local arrangement with RBP stack-frame to minimize required padding and ensure all locals are always aligned so win64:7 is obsolete.
4) Vsubpd xmm0, xmm0, zmm14 now generates an error.
New Features:
1) Add -macho64 output format support (OSX 64bit objects).
2) Added two new samples osx1.asm, osx2.asm for macho64 output.
3) Added new sample crossplatform/hello.asm demonstrating a simple console app that assembles on win64, linux and osx.
We now are finally able to run, assemble and target all platforms: Windows, Linux and OSX :)
Here is a simple hello world sample that assembles and runs on all 3 without modification:
; ####################################################################
;
; Fully cross platform 64bit Hello World Sample.
; Uses built-in @Platform to target code-blocks with UASM 2.45
;
; Windows (x64): uasm64 -c -win64 -Zp8 hello.asm
; link /machine:x64 /subsystem:console /release hello.obj msvcrt.lib
;
; Linux (x64): uasm -c -elf64 hello.asm
; gcc -o hello hello.o
;
; OSX (x64): uasm -c -macho64 hello.asm
; ld hello.o -e main -lc -o hello_app
;
; ####################################################################
include crossplatform.inc
main proto
MyFunc proto
.code
main PROC
invoke MyFunc
IF @Platform EQ WINDOWS64
invoke ExitProcess,0
ELSE
mov eax,SYS_EXIT
syscall
ENDIF
ret
main ENDP
MyFunc PROC
invoke CPRINTF, "Hello world!\n"
ret
MyFunc ENDP
end
Enjoy! :)
John
This build also contains 2 new macros for getting 128 bit MASK:
GETMASK128 and NOTMASK128 with the result returned in desired xmm register
they are available in both 32bit and 64bit and they will use proper instructions:
movups and pxor for SSE and vmovups and vpxor for AVX
usage is :
GETMASK128 xmmreg, fieldmask for field
GETMASK128 xmmreg, recordmask for record
NOTMASK128 xmmreg, fieldmask for field
NOTMASK128 xmmreg, recordmask for record
here are some examples:
263: GETMASK128 xmm3, blow
00007FF7E87610B6 C7 05 50 43 00 00 00 00 00 00 mov dword ptr [GMASK (07FF7E8765410h)],0
00007FF7E87610C0 C7 05 4A 43 00 00 00 00 00 00 mov dword ptr [GMASK+4h (07FF7E8765414h)],0
00007FF7E87610CA C7 05 44 43 00 00 00 00 00 00 mov dword ptr [GMASK+8h (07FF7E8765418h)],0
00007FF7E87610D4 C7 05 3E 43 00 00 00 FF 00 00 mov dword ptr [GMASK+0Ch (07FF7E876541Ch)],0FF00h
00007FF7E87610DE 0F 10 1D 2B 43 00 00 movups xmm3,xmmword ptr [GMASK (07FF7E8765410h)] ;XMM3 = 0000FF00000000000000000000000000
264: NOTMASK128 xmm2, blow
00007FF7E87610E5 C7 05 21 43 00 00 00 00 00 00 mov dword ptr [GMASK (07FF7E8765410h)],0
00007FF7E87610EF C7 05 1B 43 00 00 00 00 00 00 mov dword ptr [GMASK+4h (07FF7E8765414h)],0
00007FF7E87610F9 C7 05 15 43 00 00 00 00 00 00 mov dword ptr [GMASK+8h (07FF7E8765418h)],0
00007FF7E8761103 C7 05 0F 43 00 00 00 FF 00 00 mov dword ptr [GMASK+0Ch (07FF7E876541Ch)],0FF00h
00007FF7E876110D 0F 10 15 FC 42 00 00 movups xmm2,xmmword ptr [GMASK (07FF7E8765410h)]
00007FF7E8761114 66 0F EF 15 04 43 00 00 pxor xmm2,xmmword ptr [NOTMASK (07FF7E8765420h)] ;XMM2 = FFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF
265: GETMASK128 xmm3, MYREC128
00007FF7E876111C C7 05 EA 42 00 00 FF FF FF FF mov dword ptr [GMASK (07FF7E8765410h)],0FFFFFFFFh
00007FF7E8761126 C7 05 E4 42 00 00 FF FF FF FF mov dword ptr [GMASK+4h (07FF7E8765414h)],0FFFFFFFFh
00007FF7E8761130 C7 05 DE 42 00 00 FF FF FF FF mov dword ptr [GMASK+8h (07FF7E8765418h)],0FFFFFFFFh
00007FF7E876113A C7 05 D8 42 00 00 FF FF FF FF mov dword ptr [GMASK+0Ch (07FF7E876541Ch)],0FFFFFFFFh
00007FF7E8761144 0F 10 1D C5 42 00 00 movups xmm3,xmmword ptr [GMASK (07FF7E8765410h)] ;XMM3 = FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
266: NOTMASK128 xmm2, MYREC128
00007FF7E876114B C7 05 BB 42 00 00 FF FF FF FF mov dword ptr [GMASK (07FF7E8765410h)],0FFFFFFFFh
00007FF7E8761155 C7 05 B5 42 00 00 FF FF FF FF mov dword ptr [GMASK+4h (07FF7E8765414h)],0FFFFFFFFh
00007FF7E876115F C7 05 AF 42 00 00 FF FF FF FF mov dword ptr [GMASK+8h (07FF7E8765418h)],0FFFFFFFFh
00007FF7E8761169 C7 05 A9 42 00 00 FF FF FF FF mov dword ptr [GMASK+0Ch (07FF7E876541Ch)],0FFFFFFFFh
00007FF7E8761173 0F 10 15 96 42 00 00 movups xmm2,xmmword ptr [GMASK (07FF7E8765410h)]
00007FF7E876117A 66 0F EF 15 9E 42 00 00 pxor xmm2,xmmword ptr [NOTMASK (07FF7E8765420h)] ;XMM2 = 00000000000000000000000000000000
Here are the macros used:
GETMASK128 MACRO reg:REQ, field:REQ
IFNDEF GMASK
.data
GMASK OWORD 0
ENDIF
.code
IF @Arch EQ 1
movups reg, MASK field
ELSE
vmovups reg, MASK field
ENDIF
ENDM
NOTMASK128 MACRO reg:REQ, field:REQ
IFNDEF GMASK
.data
GMASK OWORD 0
ENDIF
IFNDEF NOTMASK
.data
NOTMASK OWORD -1
ENDIF
.code
IF @Arch EQ 1
movups reg, MASK field
pxor reg, NOTMASK
ELSE
vmovups reg, MASK field
vpxor reg, reg, NOTMASK
ENDIF
ENDM
As you can see GETMASK128 creates global GMASK to store 128 bit data and than load it to xmm register
if GMASK is already created it will reuse it so that we don't create a new global every time
so, the GMASK is available to use it as many times as you want, after you have used GETMASK128 first
EG:
263: GETMASK128 xmm3, blow
00007FF7476910B6 C7 05 50 43 00 00 00 00 00 00 mov dword ptr [GMASK (07FF747695410h)],0
00007FF7476910C0 C7 05 4A 43 00 00 00 00 00 00 mov dword ptr [GMASK+4h (07FF747695414h)],0
00007FF7476910CA C7 05 44 43 00 00 00 00 00 00 mov dword ptr [GMASK+8h (07FF747695418h)],0
00007FF7476910D4 C7 05 3E 43 00 00 00 FF 00 00 mov dword ptr [GMASK+0Ch (07FF74769541Ch)],0FF00h
00007FF7476910DE 0F 10 1D 2B 43 00 00 movups xmm3,xmmword ptr [GMASK (07FF747695410h)] ;XMM3 = 0000FF00000000000000000000000000
264: movups xmm0, GMASK
00007FF7476910E5 0F 10 05 24 43 00 00 movups xmm0,xmmword ptr [GMASK (07FF747695410h)] ;XMM0 = 0000FF00000000000000000000000000
NOTMASK128 creates GMASK (if not already created) and NOTMASK (if not already created)
you can use them the same way as for the GMASK above
These macros are built in UASM and cooperate with the functions inside it, they can not be used outside of UASM
We have implemented another useful macro for 64 bit only, because 32 bit can use push and pop while it is dangerous to do it in 64 bit if you don't know what are you doing: REGS15STORAGE
REGS15STORAGE MACRO
IFNDEF RRAX
.data?
RRAX dq ?
RRCX dq ?
RRDX dq ?
RRBX dq ?
RRDI dq ?
RRSI dq ?
RRBP dq ?
RRSP dq ?
RR8 dq ?
RR9 dq ?
RR10 dq ?
RR11 dq ?
RR12 dq ?
RR13 dq ?
RR14 dq ?
RR15 dq ?
RXMM0 OWORD ?
RXMM1 OWORD ?
RXMM2 OWORD ?
RXMM3 OWORD ?
RXMM4 OWORD ?
RXMM5 OWORD ?
RXMM6 OWORD ?
RXMM7 OWORD ?
ENDIF
.code
ENDM
You can use it anywhere, however, globals will be created only ones, so, you still need to know what are you doing.
These globals can be used for temporary data as well.
Hi
While looking at the disassembly I found a minor issue. I'm assembling with the following switches
.xmm
option casemap:none
option dotname
option frame:auto
option win64:8
option stackbase:rsp
When a proc argument is not referenced, then it should not be stored in the shadow area. Now it seems that UASM is confused when structure member with the same name as the argument is used. In the following example you can see how changing the argument name the disassembled code doesn't contain this additional line.
Source:
MyProc proc dVar:DWORD
mov XXX.dVar, ecx
ret
MyProc endp
Disassembly:
mov qword ptr [dVar],rcx <----
mov dword ptr [XXX],ecx
ret
Source:
MyProc proc dVar_:DWORD
mov XXX.dVar, ecx
ret
MyProc endp
Disassembly:
mov dword ptr [XXX],ecx
ret
The code looks like
MyStruc struc
dVar DWORD ?
MyStruc ends
.data
XXX MyStruc {}
.code
MyProc proc dVar_:DWORD
mov XXX.dVar, ecx
ret
MyProc endp
start proc
invoke MyProc, 123h
invoke ExitProcess, 0
start endp
end start
Regards, Biterider
I can not produce that error :icon_eek:
here is the source:
.xmm
option casemap:none
option dotname
option frame:auto
option win64:8
option stackbase:rsp
ExitProcess proto :dword
MyStruc struc
dVar DWORD ?
MyStruc ends
.data
XXX MyStruc <>
.code
MyProc proc dVar_:DWORD
mov XXX.dVar, ecx
ret
MyProc endp
start proc
invoke MyProc, 123h
invoke ExitProcess,0
start endp
end start
and here is the output:
--- biter.asm ------------------------------------------------------------------
20:
21:
22: MyProc proc dVar_:DWORD
23: mov XXX.dVar, ecx
00007FF7ED481020 89 0D DA 3F 00 00 mov dword ptr [XXX (07FF7ED485000h)],ecx
24: ret
00007FF7ED481026 C3 ret
25: MyProc endp
26:
27:
28: start proc
00007FF7ED481027 48 83 EC 28 sub rsp,28h
29: invoke MyProc, 123h
00007FF7ED48102B B9 23 01 00 00 mov ecx,123h
00007FF7ED481030 E8 EB FF FF FF call MyProc (07FF7ED481020h)
30: invoke ExitProcess,0
00007FF7ED481035 33 C9 xor ecx,ecx
00007FF7ED481037 E8 02 10 00 00 call ExitProcess (07FF7ED48203Eh)
--- No source file -------------------------------------------------------------
I can confirm I'm receiving the same output as Habran:
00007FF7AFD31000 mov dword ptr [7FF7AFD33000h],ecx
00007FF7AFD31006 ret
Package and repositories have been updated again to fix another minor issue.
Latest version: 2.45.4
John
Hi
Here ist the debugger disassembly
MyProc1:
mov qword ptr [dVar],rcx
mov dword ptr [XXX (0EB3000h)],ecx
ret
MyProc2:
mov dword ptr [XXX (0EB3000h)],ecx
ret
start:
sub rsp,28h
mov ecx,123h
call MyProc1 (0EB1000h)
mov ecx,123h
call MyProc2 (0EB100Ch)
add rsp,28h
ret
from the following code
.xmm
option casemap:none
option dotname
option frame:auto
option win64:8
option stackbase:rsp
MyStruc struc
dVar DWORD ?
MyStruc ends
.data
XXX MyStruc <>
.code
MyProc1 proc dVar:DWORD
mov XXX.dVar, ecx
ret
MyProc1 endp
MyProc2 proc dVar_:DWORD
mov XXX.dVar, ecx
ret
MyProc2 endp
start proc
invoke MyProc1, 123h
invoke MyProc2, 123h
ret
start endp
end start
UASM Version 2.45.1.0
Regards, Biterider
Found the problem and fixed.
I imagine this is a long standing one.
STRUCT.FIELD symbol searches, don't track any sort of scope, so if a parameter and a field have the same name the local (probably the parameter) gets picked up first.
Dos1.asm - tiny model -bin switch from samples gives wrong start label error :icon_cool:
Will check it out :) thanks!