The MASM Forum
64 bit assembler => 64 Bit Assembler => Topic started by: Misha paranski on June 14, 2018, 09:08:49 PM
-
Greetings,
I'm creating a common header for masm 32bit and 64bit, and i have the following macro:
IFDEF RAX
REG_AX textequ <rax>
ELSE
REG_AX textequ <eax>
ENDIF
; Copy the value from requested member in the BOOK structs array
; to the general purpose register.
GET_BOOK_MEMBER MACRO Member, BookIndex
mov REG_AX, gBooks
add REG_AX, SIZEOF BOOK * BookIndex
assume REG_AX:PTR BOOK
mov REG_AX, [REG_AX].Member
ENDM
I'm compling using visual studio, and the compliation FAILS!!! with ml64.exe with the following errors:
A2008: syntax error: rax
A2008: syntax error: rax
If i remove the "assume REG_AX:PTR BOOK" it works.... the assume statement works in 32bit. What did i do wrong? i want to
use rax as a pointer to a struct.
-
It is safer to use a global switch (credits to rrr (http://masm32.com/board/index.php?topic=5491.msg58912#msg58912)):
if @AssembleAs64bit
SIZE_P equ <QWORD> ; int and long are 32-bit, pointer is 64-bit
else
SIZE_P equ <DWORD> ; int, long, and pointer are 32-bit
rax equ eax
rcx equ ecx
rdx equ edx
rsi equ esi
rdi equ edi
rbx equ ebx
rbp equ ebp
rsp equ esp
endif
This works like a charm with ML/ML64, UAsm, AsmC and JWasm (-> 64-bit assembly with RichMasm (http://masm32.com/board/index.php?topic=5314.msg59884#msg59884)).
The principle is simple: You write all code using rax for pointers and pointer-sized variables; when assembled as 32-bit code, rax is not a keyword, so the preprocessor translates it to eax.
-
Thank you for the reply!
I'm still getting the same errors...
Here's the full code:
HARRY_POTTER = 0
IFDEF RAX
EXTERN gBooks:NEAR
SIZE_P equ <QWORD> ; int and long are 32-bit, pointer is 64-bit
_gBooks textequ <gBooks>
ELSE
EXTERN _gBooks:NEAR
SIZE_P equ <DWORD> ; int, long, and pointer are 32-bit
rax equ eax
ENDIF
BOOK struc
Name SIZE_P ?
Length SIZE_P ?
BOOK endS
; Copy the value from requested member in the BOOK struct
; to the general purpose register rax.
GET_HOOK_MEMBER MACRO Member, BookIndex
mov rax, _gBooks
add rax, SIZEOF BOOK * BookIndex
assume rax:PTR BOOK
mov rax, [rax].Member
assume rax:nothing
ENDM
;Get the name in rax
BOOK_NAME MACRO BookIndex
GET_BOOK_MEMBER Name, BookIndex
ENDM
;Get the length in rax
BOOK_LENGTH MACRO BookIndex
GET_BOOK_MEMBER Length, BookIndex
ENDM
I'm still getting
"syntax error: rax"
"undefined symbol: Length"
"undefined symbol: Name"
When using these macros in my assembly code.
If i remove the "ASSUME rax: ptr BOOK", it compiles... but i need that statement.
-
It is probably the case that ML64 treats registers as key words and won't let you equate them to anything else.
-
Well... this is literally my code now:
.CODE
Foo PROC
ASSUME rax:NOTHING
Foo ENDP
END
And i'm getting the same errors.. still:
Severity Code Description Project File Line Suppression State
Error A2008 syntax error : rax foo_project foo.asm 3 Severity Code Description Project File Line Suppression State
Error MSB3721 The command "ml64.exe /c /nologo /Zi /Fo"C:\foo\x64\Release\foo.obj"" /W3 /errorReport:prompt /foo.asm" exited with code 1. foo_project C:\Program Files\MSBuild\Microsoft.Cpp\v4.0\V140\BuildCustomizations\masm.targets 50
This is indeed... weird.. i'm not sure what to do now.. it doesn't like the "ASSUME" directive. Is it obsolete?
-
ML64 is indeed weird. Your code assembles fine with UAsm. Give it a try...
Otherwise, use an equate instead of assume:
book equ [rax.BOOK]
Mov rdx, book.xName
Mov rcx, book.xLength
I added the x because Name and Length are reserved words. Change your struct.
-
Maybe this?
assume rax:ptr StructureName
mov rsi, [rax].whatever
assume rax:nothing
-
Late to the party, nothing new. Story of my life.
ml64
MODEL STRUCT
m_MyValue0 dq ?
m_MyValue1 dq ?
m_MyValue2 dq ?
m_MyValue3 dq ?
MODEL ENDS
Some64bit_Croc proc
local TheModel:MODEL ; and she's looking good.
; assume rcx:ptr TheModel <- syntax error : rcx (A2008)
lea rcx, TheModel
mov qword ptr[rcx][MODEL.m_MyValue0], 080000000h ; Note "qword ptr" not needed, essential aesthetics IMAO.
mov qword ptr[rcx][MODEL.m_MyValue1], 07FFFFFFFh
mov qword ptr[rcx][MODEL.m_MyValue2], 0FEEDABBEh
mov rax, 0FEEDABBEh
mov qword ptr[rcx][MODEL.m_MyValue3], rax
mov qword ptr[rcx].MODEL.m_MyValue3, rax ; <- alternative syntax
mov qword ptr[rcx+MODEL.m_MyValue3], rax ; <- alternative syntax
; assume rcx:nothing <- syntax error : rcx (A2008)
; Also look carefully at the values held
; by m_MyValue0,1,2,3 after operations.
; Compare 0 with 1.
; Note dissimilarity between 2 and 3.
...
ret
Some64bit_Croc endp
-
Try
mov TheModel.m_MyValue0, 080000000h
instead of
mov qword ptr[rcx][MODEL.m_MyValue0], 080000000h
-
Thank you very much jj.
I need this syntax for OOP.
CModel_Initialize proc
mov [rax].CModel.m_ModelCaller, rdi
mov rdi, rax
mov [rdi].CModel.m_TextureCount, rcx
mov [rdi].CModel.m_TextureFile[0], rdx
mov [rdi].CModel.m_TextureFile[8], r8
mov [rdi].CModel.m_TextureFile[16], r9
call (CModel ptr[rdi]).LoadModelMesh
cmp [edi].m_ModelType, BumpType
jne TypeBump
call (CModel ptr[rdi]).CalculateBumpVectors
TypeBump:
call (CModel ptr[rdi]).InitializeBuffers
call (CModel ptr[rdi]).LoadTexture
mov rdi, [rdi].CModel.m_ModelCaller
ret
CModel_Initialize endp
-
I need this syntax for OOP
More choices ;-)
MyModel equ [rax.MODEL]
lea rax, TheModel
mov MyModel.m_MyValue0, 080000000h
mov TheModel.m_MyValue0, 080000000h
mov qword ptr[rax][MODEL.m_MyValue0], 080000000h