I think the most reasonable starting point would be to learn how to access a 2-dimensional array with MASM. The information on the linked AoA page should make this relatively easy, start at 5.6.2 Multidimensional Arrays and continue through 5.6.2.4 Accessing Multidimensional Array Elements in Assembly Language. I think you should start with a 32-bit console app, because it will be easier to code and debug, and then after you get it working translate it to 16-bit. For ease of use I think you should encapsulate the code in a procedure, one to get an array element, and one to set an array element.
Note that the page shows 16-bit code, and the array elements are 16-bit words. Translating it to 32-bit code can be as simple as substituting 32-bit registers for the 16-bit registers and 32-bit dwords for the array elements, with the complication that to allow for the doubling in the size of the array elements the:
add ax, ax
Should be replaced with:
add eax, eax
add eax, eax
Or better:
shl eax, 2
Or you can reduce the number of instructions required by taking advantage of the additional addressing modes available in 32-bit code, but I’ll leave that explanation to someone else, after you demonstrate a willingness to do something beyond “research”.
Here is a 32-bit template with some test code (that depends on a working MASM32 installation) where for simplicity I reduced the array from the 8x4 in the AoA example to 4x4.
;==============================================================================
include \masm32\include\masm32rt.inc
;==============================================================================
.data
array dd 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
.code
;==============================================================================
;--------------------------------------------------------------------------
; 0 1 2 3
; ---------------
; 0 | 00 01 02 03
; 1 | 04 05 06 07
; 2 | 08 09 10 11
; 3 | 12 13 14 15
;
; For a row major ordered array:
; Element_Address = Base_Address+(colindex*row_size+rowindex)*Element_Size
;--------------------------------------------------------------------------
;----------------------------------------------------------------------
; The convention for returning a 32-bit integer is to leave it in EAX.
;----------------------------------------------------------------------
Get proc colindex:DWORD, rowindex:DWORD
; your code goes here
ret
Get endp
Set proc colindex:DWORD, rowindex:DWORD, value:DWORD
; your code goes here
ret
Set endp
;==============================================================================
start:
;==============================================================================
invoke Get, 0, 0
printf("%d\n", eax)
invoke Get, 0, 1
printf("%d\n", eax)
invoke Get, 0, 2
printf("%d\n", eax)
invoke Get, 0, 3
printf("%d\n", eax)
invoke Get, 1, 0
printf("%d\n", eax)
invoke Get, 1, 1
printf("%d\n", eax)
invoke Get, 1, 2
printf("%d\n", eax)
invoke Get, 1, 3
printf("%d\n", eax)
invoke Get, 2, 0
printf("%d\n", eax)
invoke Get, 2, 1
printf("%d\n", eax)
invoke Get, 2, 2
printf("%d\n", eax)
invoke Get, 2, 3
printf("%d\n", eax)
invoke Get, 3, 0
printf("%d\n", eax)
invoke Get, 3, 1
printf("%d\n", eax)
invoke Get, 3, 2
printf("%d\n", eax)
invoke Get, 3, 3
printf("%d\n\n", eax)
invoke Set, 0, 0, 0
invoke Get, 0, 0
printf("%d\n", eax)
invoke Set, 0, 1, -1
invoke Get, 0, 1
printf("%d\n", eax)
invoke Set, 0, 2, -2
invoke Get, 0, 2
printf("%d\n", eax)
invoke Set, 0, 2, -3
invoke Get, 0, 2
printf("%d\n\n", eax)
invoke Set, 3, 0, -12
invoke Get, 3, 0
printf("%d\n", eax)
invoke Set, 3, 1, -13
invoke Get, 3, 1
printf("%d\n", eax)
invoke Set, 3, 2, -14
invoke Get, 3, 2
printf("%d\n", eax)
invoke Set, 3, 2, -15
invoke Get, 3, 2
printf("%d\n\n", eax)
inkey
exit
;==============================================================================
end start