0

So I’ve been writing this program that should take an array of pointers of a custom struct (DbRecord). My code is currently set up to hold 512 different pointers to DbRecord structs. I’ve been attempting to write a function readArray that will iterate through the pointers and print out the full contents of the DbRecords. As can be seen in the code, I am using the windows console api. The problem is I can’t figure out how to write the function, I have a picture in my mind as too the pointers as the array elements and then possibly using an offset to access the fields in the struct. One of my attempts involved a LEA to add the offset to the address of the current element, but the LEA did not behave as I expected.

Here is the code, I took out the different attempts because it was turning in too a mess:

.386
.model flat, stdcall
option casemap :none

include windows.inc
include user32.inc
include kernel32.inc

addElement PROTO: ptr DbRecord
readArray PROTO

.data?
    DbRecord struct
        Id      dd  ?
        WordOne     db 32   dup(?) ; db is define byte, set value of byte
        WordTwo     db 32   dup(?)
        WordThree   db 32   dup(?)
        Year        dd  ?
    DbRecord ends

    array dword 512 dup(?)      ; pointer in memory to start of array
;   newElementPointer DbRecord <>
    hStdOut dd ?
    bytesWritten dd ?

.data
    arrayCount dd 0
    hello db 'Hello World!', 0

.code
main proc
    LOCAL DbRecord01:DbRecord
    LOCAL DbRecord02:DbRecord
    mov [DbRecord01.Id], 1;

    ; any other way than one character at a time?
    mov byte ptr [DbRecord01.WordOne], 'D'
    mov byte ptr [DbRecord01.WordOne + 1], 'o'
    mov byte ptr [DbRecord01.WordOne + 2], 'g'
    mov byte ptr [DbRecord01.WordOne + 3], 0

    mov byte ptr [DbRecord01.WordTwo], 'C'
    mov byte ptr [DbRecord01.WordTwo + 1], 'a'
    mov byte ptr [DbRecord01.WordTwo + 2], 't'
    mov byte ptr [DbRecord01.WordTwo + 3], 0

    mov byte ptr [DbRecord01.WordThree], 'E'
    mov byte ptr [DbRecord01.WordThree + 1], 'y'
    mov byte ptr [DbRecord01.WordThree + 2], 'e'
    mov byte ptr [DbRecord01.WordThree + 3], 0
    mov [DbRecord01.Year], 2022;

    mov [DbRecord02.Id], 2;

    ; any other way than one character at a time?
    mov byte ptr [DbRecord02.WordOne], 'c'
    mov byte ptr [DbRecord02.WordOne + 1], 'a'
    mov byte ptr [DbRecord02.WordOne + 2], 'r'
    mov byte ptr [DbRecord02.WordOne + 3], 0

    mov byte ptr [DbRecord02.WordTwo], 'H'
    mov byte ptr [DbRecord02.WordTwo + 1], 'o'
    mov byte ptr [DbRecord02.WordTwo + 2], 'u'
    mov byte ptr [DbRecord02.WordTwo + 3], 's'
    mov byte ptr [DbRecord02.WordTwo + 3], 'e'
    mov byte ptr [DbRecord02.WordTwo + 3], 0

    mov byte ptr [DbRecord02.WordThree], 'W'
    mov byte ptr [DbRecord02.WordThree + 1], 'i'
    mov byte ptr [DbRecord02.WordThree + 2], 'n'
    mov byte ptr [DbRecord02.WordThree + 3], 'd'
    mov byte ptr [DbRecord02.WordThree + 4], 'o'
    mov byte ptr [DbRecord02.WordThree + 5], 'w'
    mov byte ptr [DbRecord02.WordThree + 6], 's'
    mov byte ptr [DbRecord02.WordThree + 7], 0

    mov [DbRecord02.Year], 2002;
        
    invoke GetStdHandle, STD_OUTPUT_HANDLE
    mov [hStdOut], eax

    invoke WriteConsole, hStdOut, offset hello, sizeof hello, offset bytesWritten, NULL
    invoke addElement, addr DbRecord01
    invoke addElement, addr DbRecord02
    invoke readArray

    ret
main endp

addElement proc uses edx DbRecordPointer: ptr DbRecord
    Local newElementPointer: Dword
    invoke VirtualAlloc, NULL, sizeof DbRecord, MEM_COMMIT, PAGE_READWRITE
    mov newElementPointer, eax
    invoke RtlMoveMemory, eax , DbRecordPointer, sizeof DbRecord
    mov edx, arrayCount
    mov dword ptr  [array +4*edx], eax
    inc edx
    mov arrayCount, edx

    ret
addElement endp


readArray proc

    ret
readArray endp



end main



debugging_info

readArray proc
    local current: dword


    lea eax, [array + offset DbRecord.WordOne]
    ;.while current != 0

        invoke WriteConsole, hStdOut, eax,3, offset bytesWritten, NULL

    ;.endw

    ret
readArray endp
11
  • 2
    Yeah well you should add back the attempt you think most promising :) Commented Jan 17, 2023 at 15:50
  • Well, I closed my notepad++ last night and didn’t really save the attempt, I am sure I rewrite the one I spent the most time on. But in the debugger I can get this in the readArray function, so I believe things are correctly setup in memory. Commented Jan 17, 2023 at 16:00
  • Multiple stores in a row to to [DbRecord02.WordTwo + 3] will just overwrite each other. Maybe you meant to increment the offset while copy/pasting? If you were using an assembler with more convenient syntax (NASM or I think FASM), you could write mov dword [...], 'Hous' to store 4 bytes with one instruction, while still keeping the code very readable for humans. You can do the same thing with MASM, but you'd have to reverse the letters or encode ASCII to a hex integer manually, taking account of the little-endian byte order. MASM and GAS suck at this. Commented Jan 17, 2023 at 16:06
  • 1
    You're not asking us to finish your code, so, what's your question? FYI, you should work out the program in a language you know well, then take that to assembly. You need to focus on what you are given and how to make that do what you need, and worry about the assembly version after you figure this out. Commented Jan 17, 2023 at 16:08
  • 1
    Your array contains pointers. You need something like mov eax, [array]; lea eax, [eax+offset DbRecord.WordOne] Commented Jan 17, 2023 at 16:25

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.