Multi dimensionnal structure and word multidimensional VARARG 64 32

Started by TouEnMasm, April 18, 2021, 04:20:30 AM

Previous topic - Next topic

TouEnMasm

I have made the test with ML and the masm32 package.
It is as usual,the many limitations of ML don't allow to do what is perfectly correct.
Use UASM,JWASM or ASMC,I have not tested,but i am sure they work.
Five minutes later,I have tested UASM,JWASM,ASMC all three are happy with the code.
You have the choice.
Fa is a musical note to play with CL

HSE

Equations in Assembly: SmplMath

LiaoMi

Hi TouEnMasm,

some ideas can be seen here: 2.2.2.1: HLA Array Types
https://www.plantation-productions.com/Webster/Win32Asm/WindowsAsmPgm/html/Ch02.html

Using SIMD to Optimize x86 Assembly Code in Array Sum Example
https://www.codeproject.com/Articles/5298048/Using-SIMD-to-Optimize-x86-Assembly-Code-in-Array

SETL (SET Language) is a very high-level programming language based on the mathematical theory of sets. It was originally developed by (Jack) Jacob T. Schwartz at the New York University (NYU) Courant Institute of Mathematical Sciences in the late 1960s.
https://en.wikipedia.org/wiki/SETL


INCLUDE Irvine32.inc
INCLUDE Macros.inc

.data
MAX_ROWS = 5                                            ; constant for num rows
MAX_COLS = 5                                            ; constant for num cols

my2DArray dword MAX_ROWS * MAX_COLS dup(0)                ; creates 2-d array
spaceStr byte " ",0                                        ; for displaying a space
inputRow byte "Enter Row(Type 99 To Exit): ",0            ; for displaying massage for entering a Row
inputColumn byte "Enter Column:",0                        ; for displaying massage for entering a Col
currentValue byte "The daisies there was:",0            ; for displaying massage for a Current value
inputValue byte "Daisies Gathered:",0                    ; for displaying massage for entering a New Valuse
Bye byte "Have a Wonderful Day!!!",0                    ; Displaying Have a wonderful day massage
displayHeader byte "Filed of Daisies:",0                ; string to display before report

mainPoint dword ?
randRow dword ?                                            ; holds random row
randCol dword ?                                            ; holds random row
randValue dword ?                                        ; holds random value to assign into array
replaceRow dword ?                                        ; holds the replaced Row
replaceColumn dword ?                                    ; holds the replaced Column
newValue dword ?                                        ; holds the new value


multiply dword 8                                        ;
divide dword 10
addnum sdword 0                                            ; add # for Row
addnumc sdword 0                                        ; add # for Column


.code
main PROC
    CALL Clrscr
    CALL randomize                    ; stir the pot

                           
                             
    MOV ECX, MAX_ROWS * MAX_COLS    ; Move 2-D array to ECX
    MOV EDI, offSet my2DArray        ; display prompt 2-D array

genLoop:
   
    MOV EAX, 100                    ; load EAX with upper bound for random value
    CALL randomRange                ; generate random value 0..upper bound-1
    MOV randValue, EAX
    MOV [EDI], EAX
    add EDI, type my2DArray            ; edi is to stick value into array
   

    loop genLoop


SecondLoop:
    Call crlf
   
    Call crlf
    mWrite "Filed of Daisies:"       
    Call crlf
    Call crlf
                                    ; at this point my2DArray is full of 0s
                                    ; call proc to display array
    CALL displayMy2DArray                               
   
   
    MOV EDX, offset inputRow        ; display prompt inputRow
    CALL writestring                ; display input Row message
    CALL readDec                    ; display random row
    MOV replaceRow, EAX                ; store random # into randRow
       
    CMP replaceRow, 99                ; quit the program when typing # 99
    JE TakeCare                        ; get number
    MOV randRow, EAX                ; store in memory

    MOV EDX, offset inputColumn        ; display prompt inputColumn
    CALL writestring                ; display input Column
    CALL readDec                    ; get number
    MOV replaceColumn, EAX            ; store in memory

    CALL CRLF                        ;\n
   

    MOV EDX, offset currentValue    ; display prompt currentValue
    CALL writestring                ; display Currently the value message
    MOV EAX, replaceRow                ; get number
    MOV EBX, replaceColumn            ; store in memory

    CALL getElementOfArray            ; get element at  [replaceRow][replaceColumn] to newValue
    CALL WriteDec                    ; display get element of array
    CALL CRLF                        ;\n
   
   
   
   
    ;;;;;;;;;;;
    ;=============================
    ; Multiplication
    ;=============================
;    mov edx, 0                                    ; 0 out edx in preparation for iMul
;    MOV EAX, replaceRow                ; get number
;    MOV EBX, replaceColumn            ; store in memory
;
;    fld    multiply
;    fmul
;    fst    newValue
;                                        ; eax*ebx ==> edx:eax contains product
;    mov newValue, eax                            ; hold on to product                   
;
;    ;=============================
;    ; divition
;    ;=============================
;    MOV EAX, replaceRow                ; get number
;    MOV EBX, replaceColumn            ; store in memory
;
;    cdq                                            ; prepares edx: eax iDiv
;
;    ;iDiv eax                                    ; eax/ebx ==> edx:eax contains quotient, edx
;    mov divide, eax                            ; hold on to quotient
;    MOV newValue, EAX                ; store in memory
;    mov mainPoint, edx                            ; hold on to remainder


    ;;;;;;;;;;
   
    MOV EDX, offset inputValue        ; display prompt inputValue
    CALL writestring                ; display input Value message
    CALL readDec                    ; get number
    MOV newValue, EAX                ; store in memory
   
    MOV EAX, replaceRow                ; load eax with new added row
    MOV EBX, replaceColumn            ; load ebx with new added column
    MOV ECX, newValue                ; load ecx with new added value
    ;CALL WriteDec   
       
   
   
                           
    CALL setElementOfArray            ; set element at [replaceRow][replaceColumn] to newValue

   
    JMP SecondLoop                    ; Jump the second loop to TakeCare
   

TakeCare:


CALL CRLF                            ;\n
MOV EDX, offset Bye                    ; display prompt Good Bye message
CALL writestring                    ; display Good Bye message
CALL CRLF                            ;\n

    exit
main ENDP
        ; =============================================
        ; setElementOfArray procedure expects 3 parameters
        ;    EAX row
        ;    EBX col
        ;    ECX value
        ;
        ;  logiCALLy this will be like:  my2DArray[EAX,EBX]=ECX
setElementOfArray PROC uses EDX EDI

    MOV EDX, 0                ; prepare for mul

    push EBX                ; put EBX the column on the stack

    MOV EBX, MAX_COLS*4        ; calculate the number of bytes in a row
                            ; since EAX has the rowNum
    mul EBX                    ; EAX is now rowNum * MAX_COLS*4 - total bytes before current row
    MOV EDI, EAX            ; put byte offset into EDI

    pop EAX                    ; we had put EBX on the stack which was the colNum
                            ; put that on EAX

    MOV EBX, 4                ; load EBX with 4 for size of element
    mul EBX                    ; EAX is now colNum*4 which is the byte offset in the current row
    add EDI, EBX            ; EDI is now rowNum * MAX_COLS*4 + colNum*4
   
   
                            ; which is the byte offset from the beginning
                            ; of the array to this element rowNum,colNum
   

    MOV my2DArray[EDI], ECX      ; stick value in ECX into array
    mov ecx, 0
    MOV multiply, eax
    mul edi
   
                            ; phew!
    ret
setElementOfArray ENDP

        ; =============================================
        ; displayMy2DArray procedure expects no parameters
        ;       
displayMy2DArray PROC uses EDX EDI ECX EAX

    mov ecx, MAX_COLS                    ; move ecx to coulmn
    push eax
    mov eax, 0
    mWrite "      "                        ; Sapce
    call padOnLeft
dispCol:                                ; display Column Numbers
    call writeDec
    mWrite "  "                            ; Sapce
    call padOnLeft                        ; pad with spaces
    inc eax
    loop dispCol

    call crlf                            ;\n
    pop eax

    mov ecx, MAX_COLS
    mov eax, 0
    mWrite "    "                        ; Sapce
    call padOnLeft                        ; pad with spaces
UnderLine:
    mWrite " ---- "                        ; line of the col
    loop UnderLine                       
    call crlf                            ;\n

    mov edi, 0                            ; load edi with 0 offset

    mov ecx, MAX_ROWS                    ; load ecx with number of rows so we can loop through rows

displayRow:                                ; top of outerloop on rows
   
    Mov eax, addnum
    call padOnLeft
    call writedec   
    inc addnum
   
    mWrite" :"
    push ecx                            ; preserve ecx from outloop to use innerloop

    mov ecx, MAX_COLS                    ; load ecx with number of cols so we can loop through cols
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
displayCol:                                ; top of innerloop on cols
    mov eax, my2DArray[edi]                ; move element from array to eax for display
    mWrite " "
    call padOnLeft                        ; pad with spaces
   
                                        ; for debugging purposes show . instead of 0
                        ; display .
       

    .if EAX == 0                        ;  if element to display is 0
        push EAX                        ; preserve EAX
        MOV al, '.'                        ; display .
        CALL writeChar
        pop EAX                            ; restore EAX
    .else
        CALL writedec                    ; display element
    .endIf

    ;call desplayCarret

    MOV EDX, offset spaceStr        ; display a space
        CALL writestring                    ; display element
   

    add EDI,4                            ; advance dsi to next element

   
    loop displayCol                        ; bottom of innerloop (loop on cols)

   
    CALL CRLF                            ; now that a row has been displayed, MOVe to beginning of next line for next row

    pop ECX                                ; restore ECX for outerloop on rows

    loop displayRow                        ; bottom of outerloop (loop on rows)
       
   

    mov addnum, 0                        ; Start with 0 # Row
    mov addnumc, 0                        ; Start with 0 # Column

    ret                                    ; done with this method
displayMy2DArray ENDP

        ; =============================================
        ; padOnLeft procedure expects 1 parameters
        ;        EAX with value to pad
        ;       
padOnLeft PROC uses EDX

    .if EAX < 1000
        MOV EDX, offset spaceStr            ; display space
        CALL writestring
    .endif

    .if EAX < 100
        MOV EDX, offset spaceStr            ; display space
        CALL writestring
    .endif

    .if EAX < 10
        MOV EDX, offset spaceStr            ; display space
        CALL writestring
    .endif
           
    ret
padOnLeft ENDP
        ; =============================================
        ;    getElementOfArray procedure expects 2 parameters
        ;    EAX row
        ;    EBX col
        ;
        ;  logiCALLy this will be like:  my2DArray[EAX,EBX]=ECX
getElementOfArray PROC
   
    MOV EDX, 0                ; prepare for mul

    push EBX                ; put EBX the column on the stack

    MOV EBX, MAX_COLS*4        ; calculate the number of bytes in a row
                            ; since EAX has the rowNum
    mul EBX                    ; EAX is now rowNum * MAX_COLS*4 - total bytes before current row
    MOV EDI, EAX            ; put byte offset into EDI

    pop EAX                    ; we had put EBX on the stack which was the colNum
                            ; put that on EAX

    MOV EBX, 4                ; load EBX with 4 for size of element
    mul EBX                    ; EAX is now colNum*4 which is the byte offset in the current row
    add EDI, EAX            ; EDI is now rowNum * MAX_COLS*4 + colNum*4
   
                            ; which is the byte offset from the beginning
                            ; of the array to this element rowNum,colNum
   
    MOV EAX, my2DArray[EDI]      ; stick value in EAX into array
   
                           
    ret                        ; Return
getElementOfArray ENDP

TouEnMasm

Hello,
The vararg for 32 bits seem solved.
I try now to do the same thing for 64 bits.
I there is no more than four argument,no problem they are in rcx, rdx, r8, et r9.
A little help is needed for the five,six .. arguments,They are in stack ,How find the them ?
Fa is a musical note to play with CL

TouEnMasm

#19
solved also The 64 bits form
I have tested it with uasm,jwasm and asmc64.
Little modifies  :toothy: made.The X64 and X32 directories give the two samples.
Take care that uasm dont find the fifty element at the same place    (64 bits sample debut.asm)

.If NBdim == 4
mov rdx,0
mov ecx,[rbx+12]
.if ecx == 0
jmp NullDim
.endif
;mov eax,[rbp+50h]                                           ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< uasm
mov         eax,dword ptr [rbp+30h]                       ;<<<<<<<<<<<<<<<< jwasm ,asmc64
mul ecx
add cumul,eax
.endif

     
Fa is a musical note to play with CL