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
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

[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 writemov 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.mov eax, [array]; lea eax, [eax+offset DbRecord.WordOne]