News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Use the MOV instruction to obtain the value in the array

Started by wanker742126, September 04, 2024, 05:35:02 PM

Previous topic - Next topic

wanker742126

I was writing a 64-bit Windows program and noticed something strange:
The following program can be successfully assembled using ML64, but will appear when using UASM64
"Error A2031: invalid addressing mode with current CPU setting"
--------------------------------------------------
array DD 20h DUP (1)
... ...
mov rcx,2
mov eax,array[rcx*4+8]
--------------------------------------------------
Does anyone know what's going on?

six_L

Hi,wanker742126
lea    rdx,array    ;mov    rdx,offset array
mov    rcx,2
mov    eax,[rdx+rcx*4]

rdx: the frist address of  your array
rcx: index
4: 1"DD"=4"BYTE"
Say you, Say me, Say the codes together for ever.

wanker742126

Hello Six_L
I know it can be written like this, but I would like to know why ML64 can be successfully assembled, but UASM64 cannot. Is it necessary to make any settings on the CPU?

_japheth

Quote from: wanker742126 on September 04, 2024, 10:17:47 PMI know it can be written like this, but I would like to know why ML64 can be successfully assembled, but UASM64 cannot. Is it necessary to make any settings on the CPU?

No. It's valid syntax, and if UASM refuses it, it's a bug.
Dummheit, gepaart mit Dreistigkeit - eine furchtbare Macht.

six_L

Hi,wanker742126
Quotewhy ML64 can be successfully assembled, but UASM64 cannot. Is it necessary to make any settings on the CPU?
1,ML64 is written by microsoft; UASM64 is written by John Hankinson and Branislav Habus, _japheth (our forum member). they are different assembler.
2,Assembly language syntax of ML64 is not ml32-compatible, don't support HLL features. But UASM64 does.
3,ML64 only works on MS OS; UASM64 can work on MS OS, Linux and OSX.
Say you, Say me, Say the codes together for ever.

wanker742126

Thanks for your answer, six_L and _japheth.
Maybe I have to wait until UASM supports this syntax. Or maybe try using macros.

six_L

Hi,wanker742126
QuoteMaybe I have to wait until UASM supports this syntax.
Maybe You will never be the outcome. because the register addressing is faster than the memory addressing.
Say you, Say me, Say the codes together for ever.

mineiro

;this is a simple workaround, tested in linux
;I was trying to create a macro but displacement have not been added to array offset
;so I put displacement in a register
mov rcx,2
mov edx,8
mov eax,array[ecx*sizeof dword+edx]

;+8 displacement is not being added
mov eax,array[rcx*sizeof dword+8+rdx]      ;<---
USE32
mov eax,dword ptr [array+8+ecx*4]         ;<---
USE64
I'd rather be this ambulant metamorphosis than to have that old opinion about everything

wanker742126

Today I found that ADD, SUB, MUL, and DIV can all accept array usage, but only MOV cannot.
The following program can be successfully assembled using UASM64
OPTION  CASEMAP:NONE
OPTION  WIN64:3

INCLUDELIB      KERNEL32.LIB
INCLUDELIB      USER32.LIB

MessageBoxA     PROTO   :QWORD,:QWORD,:QWORD,:DWORD
ExitProcess     PROTO   :DWORD
;*********************************************************************
.CONST
array           DD      20h DUP (1)
szCaption       DB      "TITLE",0
szText          DB      "64-BIT ASSEMBLY.",0
;*********************************************************************
.CODE
;---------------------------------------------------------------------
main    PROC
        mov     rcx,2
        add     eax,array[rcx*4+8]
        sub     eax,array[rcx*4+8]
        xor     eax,array[rcx*4+8]
        mul     array[rcx*4+8]
        div     array[rcx*4+8]
        invoke  MessageBoxA,0,OFFSET szText,OFFSET szCaption,0
        invoke  ExitProcess,0
main    ENDP
;*********************************************************************
END     main


But the program below will fail to assemble and compile, and the error occurs in the MOV line.
OPTION  CASEMAP:NONE
OPTION  WIN64:3

INCLUDELIB      KERNEL32.LIB
INCLUDELIB      USER32.LIB

MessageBoxA     PROTO   :QWORD,:QWORD,:QWORD,:DWORD
ExitProcess     PROTO   :DWORD
;*********************************************************************
.CONST
array           DD      20h DUP (1)
szCaption       DB      "TITLE",0
szText          DB      "64-BIT ASSEMBLY.",0
;*********************************************************************
.CODE
;---------------------------------------------------------------------
main    PROC
        mov     rcx,2
        mov     eax,array[rcx*4+8]
        add     eax,array[rcx*4+8]
        sub     eax,array[rcx*4+8]
        xor     eax,array[rcx*4+8]
        mul     array[rcx*4+8]
        div     array[rcx*4+8]
        invoke  MessageBoxA,0,OFFSET szText,OFFSET szCaption,0
        invoke  ExitProcess,0
main    ENDP
;*********************************************************************
END     main


six_L

you are digging the bugs of compiler, not learning the assembler language.
Come on!
the TAIWAN's frog is sitting on well and talking the vastness of sky.
Say you, Say me, Say the codes together for ever.

wanker742126

I wrote a set of macros that can somewhat resolve the issue of assembling instructions like mov eax, array[rcx*4+8] using UASM64.EXE. The principle is quite simple: analyze such instructions and convert them into the corresponding machine code. However, the implementation is rather complicated. Nonetheless, I managed to complete it.

Below is a demonstration program:

asm

OPTION  CASEMAP:NONE
OPTION  WIN64:3
INCLUDELIB      KERNEL32.LIB
INCLUDELIB      USER32.LIB
EXTRN   MessageBoxA:PROC
EXTRN   ExitProcess:PROC
INCLUDE MYFIX_ENG.INC
;*********************************************************
.DATA
button          DD      10h,20h,30h,40h
n               DD      4
szCaption       DB      "TEST MYFIX_ENG.INC",0
szText          DB      "PLEASE PRESS ANY BUTTON.",0
;*********************************************************
.CODE
;---------------------------------------------------------
main    PROC
again:  xor     rcx,rcx
        mov     rdx,OFFSET szText
        lea     r8,szCaption
        movzx   rax,WORD PTR n
        mova    r9d,button[rax*4]
        call    MessageBoxA
        dec     n
        jnz     again
        xor     ecx,ecx
        call    ExitProcess
main    ENDP
;*********************************************************
END

The mova macro used here is defined in MYFIX_ENG.INC. I've tested it, and it works fine, but there may still be oversights. If you encounter any issues, please let me know on the forum or via email: wkochih@gmail.com. Since MYFIX_ENG.INC has over 400 lines, I've compressed it into an archive.Here is MYFIX_ENG

_japheth

Hello,

Your MYFIX_ENG.INC file is pretty large. Are you sure it works with any image base? I'm asking because I vaguely remember that RIP-relative addressing is limited to direct addressing - that means, if indirect addressing is used ( based or indexed or both ), the displacement ( = offset ) is always "zero-based", never RIP-relative. As a consequence, base/indexed addressing with displacements fully work in the first 4 GB of the address space only. However, it's long ago that I examined this stuff, maybe I'm wrong...
Dummheit, gepaart mit Dreistigkeit - eine furchtbare Macht.

wanker742126

My MYFIX_ENG.INC can only be used in
MOV reg1,VAR[reg2*n]
MOV VAR[reg1*n],reg2
MOV Var[reg*n],imm
In three cases, reg1, reg2, and reg can only be general purposes registers, cannot be RIP. In fact, RIP cannot change its value through MOV. In addition, I also admit that MYFIX_ENG.INC is very large, with more than 400 lines, so I did not list the entire code on the forum, but downloaded its link through MEGA. Maybe you experts can simplify it :).

_japheth

Quote from: wanker742126 on September 14, 2024, 10:31:34 AMMy MYFIX_ENG.INC can only be used in
MOV reg1,VAR[reg2*n]

Ok, I did a little test:

.x64
.model flat
include MYFIX_ENG.INC

.data
db 50h dup (?)
array dd 0,1,2,3,4,5,6,7

.code
start:
xor ecx, ecx
mova eax, array[rcx*4]
mov eax, array[rcx*4]
ret
end  start

Since UASM refuses indexed addressing with symbolic displacement, I used JWasm to assemble it. DUMPBIN then displays the following relocations:

Offset    Type              Applied To         Index     Name
 --------  ----------------  -----------------  --------  ------
 00000005  ADDR32                     00000050         4  .data
 0000000C  ADDR32                     00000000         9  array

So there's indeed a difference, but the important thing is that both relocs are ADDR32. This inevitably makes  MS link complain:

Microsoft (R) Incremental Linker Version 9.00.30729.01
Copyright (C) Microsoft Corporation.  All rights reserved.

MOV64b.obj : error LNK2017: 'ADDR32' relocation to '.data' invalid without /LARGEADDRESSAWARE:NO
MOV64b.obj : error LNK2017: 'ADDR32' relocation to 'array' invalid without /LARGEADDRESSAWARE:NO
LINK90 : fatal error LNK1165: link failed because of fixup errors
[/code]

Of course, adding /LARGEADDRESSAWARE:NO to link's cmdline makes the errors disappear, but the image is then restricted to run in the first 4 GB of the address space.




Dummheit, gepaart mit Dreistigkeit - eine furchtbare Macht.

wanker742126

In fact, I just hope that UASM64.EXE can assembly the following three situations:
MOV reg1,VAR[reg2*n]
MOV VAR[reg1*n],reg2
MOV Var[reg*n],imm
I didn't expect to be able to use the entire 64-bit addressing space. So I have always misunderstood your question.