The task is: Check if the second row of a two-dimensional array is sorted in descending order. I need to do this using assembly masm. Here is the code:
.686
.model flat, stdcall
option casemap:none
include C:\masm32\include\windows.inc
include C:\masm32\include\user32.inc
include C:\masm32\include\kernel32.inc
include C:\masm32\include\masm32.inc
includelib C:\masm32\lib\user32.lib
includelib C:\masm32\lib\kernel32.lib
includeLib C:\masm32\lib\masm32.lib
.data
sConsoleTitle BYTE "Task", 0
task BYTE "Check if the second row of a two-dimensional array is sorted in descending order", 0Dh, 0Ah, 0
Arr DWORD 4, 6, 2, 8
RowSize = ($ - Arr)
DWORD 9, 4, 2, 1
DWORD 7, 3, 5, 1
DWORD 6, 8, 1, 7
resultText BYTE "Result: "
row BYTE 4
col BYTE 4
i BYTE 0
j BYTE 0
exitText BYTE "Print enter to exit....", 0Dh, 0Ah, 0
pos BYTE "Yes", 0Dh, 0Ah, 0
negative BYTE "No", 0Dh, 0Ah, 0
resultStr BYTE 16 DUP(' ')
buffer BYTE 20 DUP(?), 0
clrt BYTE 0Ah, 0Dh, 0
tab BYTE " ", 0
sum DWORD 0
.code
start:
invoke SetConsoleTitle, offset sConsoleTitle
invoke StdOut, offset task
; Show array
xor ecx, ecx
mov cl, row
mov esi, 0
loop_row_1:
push ecx
xor ecx, ecx
mov cl, col
mov ebx, 0
loop_col_1:
mov eax, Arr[esi][ebx]
push ebx
push ecx
push esi
invoke ltoa, eax, ADDR buffer
invoke StdOut, ADDR buffer
invoke StdOut, ADDR tab
pop esi
pop ecx
pop ebx
add ebx, TYPE Arr
loop loop_col_1
invoke StdOut, ADDR clrt
add esi, RowSize
pop ecx
loop loop_row_1
; Check
mov esi,1
xor ecx, ecx
mov cl, col
mov ebx, 0
mov j, 0
loop_col_2:
mov eax, Arr[esi][ebx]
cmp eax, 0
jle no
add ebx, TYPE Arr
loop loop_col_2
invoke StdOut, ADDR clrt
yes:
invoke StdOut, ADDR resultText
invoke StdOut, ADDR pos
jmp exit
no:
invoke StdOut, ADDR resultText
invoke StdOut, ADDR negative
exit:
invoke StdIn, ADDR buffer, lengthof buffer
end start
Why did I always get the possitive answer, by the way I got it always, also when I change the value of esi register to another value (this register is responsible for which string is will be checked). I have no idea what I am doing wrong. (Actually maybe I do something worng with registers, but I have an example which is almost the same as my task and I wrote the code like in this example, but the problem is still on)
You have your 2D-matrix in row-order. Therefore the elements of the row that you need to inspect will be adjacent to each other and will have been stored in consecutive dwords in memory. All you will need is a simple pointer to the start of the concerned row. With row numbering starting at 0, the formule is:
RowAddress = ArrayAddress + Row * RowSize
mov ebx, OFFSET Arr + 1 * RowSize ; Row = 1 for the second row
The task of finding out if this row is sorted in descending order translates to writing a loop that compares every 2 adjacent dwords for as long as the first value is greater or equal to the second and for as long as comparisons can be made because if you got 4 columns in the array the most pair-wise comparisons that are possible is 3.
mov ebx, OFFSET Arr + RowSize ; Start of 2nd row
movzx ecx, col
dec ecx ; Number of required comparisons
More:
mov eax, [ebx]
cmp eax, [ebx + 4]
jl No
add ebx, 4
dec ecx
jnz More
Yes:
An alternative that uses one register less and that stops as soon as the pointer reaches the last element of the row:
mov ebx, OFFSET Arr + RowSize ; Start of 2nd row
More:
mov eax, [ebx]
cmp eax, [ebx + 4]
jl No
add ebx, 4
cmp ebx, OFFSET Arr + RowSize + RowSize - 4 ; Address last element of 2nd row
jb More
Yes:
Another alternative that avoids reading the same datum twice:
mov ebx, OFFSET Arr + RowSize ; Start of 2nd row
mov edx, [ebx]
More:
add ebx, 4
mov eax, edx
mov edx, [ebx]
cmp eax, edx
jl No
cmp ebx, OFFSET Arr + RowSize + RowSize - 4 ; Address last element of 2nd row
jb More
Yes: