I have written some code for an assignment involving Assembly, and one part of the assignment involves finding the minimum value between two user inputted indexes (I and J). For the life of me I can not get it to work as the loop does not iterate properly and I cannot figure out why. Any help would be appreciated.
MinValues PROC
mov eax, PosI ;getting difference between i and j
sub PosJ, eax
mov eax, PosJ
Call WriteInt
mov IJDiff, eax
call crlf
mov ecx, IJDiff
LEA esi, Vector
add esi, PosI
add esi, PosI
add esi, PosI
add esi, PosI
mov eax, [esi]
mov MinNum, eax
NextMin:
mov eax, [esi]
call WriteInt
cmp eax, MinNum
jl Minimum
add esi, 4
Loop NextMin
ret
Minimum: mov MinNum, eax
;add esi, 4
ret
MinValues ENDP
Related
I try to put on stack the values contained by array_output but every time I print the values from the stack it prints just 0s.
If I try to print the array simple not using the stack it works.
What I do wrong?
stack_alloc:
sub esp, 1
mov al, byte [array_output + ecx]
mov byte [esp], al
add ecx, 1
cmp ebx, ARRAY_OUTPUT_LEN
cmp ebx, ecx
jg stack_alloc
cmp ebx, ARRAY_OUTPUT_LEN
cmp ebx, ecx
jg stack_alloc
You have a typo in your code. The cmp ebx, ARRAY_OUTPUT_LEN instruction should not be comparing but rather loading the EBX register.
You could correct the problem replacing the cmp with a mov but I would propose to simplify your code and just compare the index in ECX to ARRAY_OUTPUT_LEN. This will require choosing the opposite conditional branch and saves from using the additional register EBX:
xor ecx, ecx
stack_alloc:
sub esp, 1
mov al, [array_output + ecx]
mov [esp], al
inc ecx
cmp ecx, ARRAY_OUTPUT_LEN
jb stack_alloc
I'm trying to write a simple program that reverses an array. It almost works, well it works for the first half of the array anyway. The term in the middle is always "0" and then it returns to the pattern. For example, if I input: 1,2,3,4,5,6,7,8,9,10, the output will be 10,9,8,7,6,0,6,5,4,3. The order of the program is basically this:
Call to ReverseArray:
INVOKE ReverseArray,
LENGTHOF array, SIZEOF array, TYPE array, OFFSET array
ReverseArray procedure (loops through the array and calls mSwap32):
ReverseArray PROC,
len:DWORD, s:DWORD, increment:DWORD,address:DWORD
mov edx, OFFSET revArray
call WriteString
mov edi, address
mov esi, address
add esi, s
sub esi, TYPE array
mov ecx, len
shr ecx, 1
L2:
mSwap32 edi, esi
add edi, increment
sub esi, increment
loop L2
ret
ReverseArray endp
mSwap32 Macro (is given two addresses to swap):
mSwap32 MACRO address1:REQ, address2:REQ
mov edi, address1
mov esi, address2
mov eax, [esi]
push eax
mov eax, [edi]
mov [esi], eax
pop eax
mov [edi], eax
ENDM
I'm fairly certain that the error is in mSwap32...I'm sure it is some small logical error I'm missing, but no matter how much I toy with it I can not figure it out. ??
it's a WORD array
With this crucial piece of information we can solve the problems. LENGTHOF will be 10 (as before), SIZEOF will now be 20 and TYPE will now be 2.
ReverseArray PROC,
len:DWORD, s:DWORD, increment:DWORD,address:DWORD
mov edx, OFFSET revArray
call WriteString
mov edi, address
mov esi, address
add esi, s
sub esi, increment ;Better not refer to the actual array here!
mov ecx, len
shr ecx, 1
L2:
mSwap32 edi, esi
add edi, increment
sub esi, increment
loop L2
ret
ReverseArray endp
and the macro:
mSwap32 MACRO address1:REQ, address2:REQ
mov edi, address1
mov esi, address2
mov ax, [esi]
push eax
mov ax, [edi]
mov [esi], ax
pop eax
mov [edi], ax
ENDM
Shorter and still using a macro:
mSwap32 MACRO address1:REQ, address2:REQ
mov edi, address1
mov esi, address2
mov ax, [esi]
xchg ax, [edi]
mov [esi], ax
ENDM
My task here is to add a code that sorts the array with insertion sort.
'printf' function prints a string
printArray prints the array
For some reason the array doesn't get sorted, and i cant find the reason why.
Help will be appreciated.
main:
push MSG ; print welcome message
call printf
add esp,4 ; clean the stack
call printArray ;print the unsorted array
;;;;;;;;;;add code here;;;;;;;;;;
mov eax,1
loop1:
mov ebx, array
add ebx, eax
loop2:
mov esi, ebx
dec esi
mov esi, [esi] ;esi holds the value before what ebx points to
cmp [ebx], esi
ja endLoop2
mov edx, esi
mov esi, ebx
dec esi
mov ecx, [ebx]
mov [esi], ecx
mov [ebx], edx
dec ebx
cmp ebx, array
ja loop2
endLoop2:
inc eax
cmp eax, 11
jbe loop1
;;;;;;;end of your code;;;;;;;;;;;;;;
call printArray
mov eax, 1 ;exit system call
int 0x80
If your array is full of 1 byte values, use movb instead of mov when loading and storing to memory.
So we're currently studying Intel 8086 Insertion Sort Code that our professor showed us. He wanted us to figure out why the code skips the 0th element within the array and the 3rd element in the array from a code that he had taken from the web.
; void isort(int *a, int n)
; sorts the first n elements of a
;
; Parameters
; a - pointer to the array
; n - number of elements to sorts
%define a [ebp + 8]
%define n [ebp + 12]
isort:
enter 0, 0
pusha
mov ecx, 1
for:
mov ebx, ecx
imul ebx, 4
add ebx, a
mov ebx, [ebx]
mov edx, ecx
dec edx
while:
cmp edx, 0
jl while_quit
mov eax, edx
imul eax, 4
add eax, a
cmp ebx, [eax]
jge while_quit
mov esi, [eax]
mov dword [eax + 4], esi
dec edx
jmp while
while_quit:
mov [eax], ebx
inc ecx
cmp ecx, n
jl for
popa
leave
ret
And the sample array was {5, 8, 12, 2, 1, 7}. This is more for understanding the 8086 language since we just started a couple days ago, and I was wondering if anyone could explain how and what might be going wrong.
Consider what the code will do when ECX is 1:
The while loop will be entered with EBX=8 and EDX=0.
The jl while_quit will not be taken, since EDX is 0.
EBX is compared to [EAX]. That is; 8 is compared to a[0], which is 5, so the jge while_quit is taken.
mov [eax], ebx stores 8 at a[0], so your array now contains {8,8,12,2,1,7}. Clearly not what you want, since you've lost one of the original elements.
Apart from the code's logical flaw, those imul instructions are completely unnecessary since you can use scaled indices on the x86. So the sorting code can be simplified to this (I've verified that it sorts the array correctly):
mov ecx, 1
for_:
; esi = &a[holePos]
lea esi,[a + ecx*4]
; valueToInsert = a[holePos]
mov ebx, [esi]
while_:
; Did we reach the beginning of the array?
cmp esi, OFFSET a
jle while_quit
; valueToInsert < a[holePos-1] ?
cmp ebx, [esi-4]
jge while_quit
; a[holePos] = a[holePos-1]
mov eax, [esi-4]
mov [esi], eax
; esi = &a[holePos-1]
sub esi,4
jmp while_
while_quit:
; a[holePos] = valueToInsert
mov [esi], ebx
inc ecx
cmp ecx, 6
jl for_
I'm using MASM syntax, but you get the idea.
I am writing a number manipulation program, and one step is to reverse the array. So far I have
reverseArray proc
mov eax, arraySize
mov temp, eax
Imul eax, 4
mov esi, eax
mov eax, 0
mov number, 0
jne L1
L1:
cmp temp, 0
je L3
mov eax, numbers[esi]
mov tempnumbers[ecx], eax
mov eax, tempnumbers[ecx]
call writeDec
call crlf
sub esi,4
add ecx, 4
sub temp, 1
loop L1
L2:
ret
L3:
.If(number >= 0)
mov esi, 0
.ENDIF
mov eax, number
cmp eax, arraySize
je L2
mov eax, tempnumbers[esi]
mov numbers[esi], eax
add esi, 4
add number, 1
loop L3
However this only reverses about half of my array. Did I do something wrong with the esi or ecx counters? Any help would be appreciated.
Use edi instead of ecx, and set it to 0 at the start.