我的程序接受用户输入(10到200之间的整数),并打印出输入的随机数并将其存储在数组中。然后将数组排序并打印出来(请参阅下面的图像)。屏幕上还会打印数字的中位数。
我找不到错误。该程序对于小于或等于130但不大于130的数字非常适用。
TITLE Program5 (Program5.asm)
INCLUDE Irvine32.inc
; (insert constant definitions here)
MIN_INPUT = 10
MAX_INPUT = 200
LO_RANDOM = 100
HI_RANDOM = 999
.data
request DWORD 10
ask_user BYTE "How many numbers should be generated? [10 ... 200]: ", 0
error BYTE "Invalid input", 0
title_1 BYTE "The unsorted random numbers: ", 0
title_2 BYTE "The sorted list: ", 0
space BYTE " ", 0
median BYTE "The median is: ", 0
temp DWORD 0
list DWORD MAX_INPUT DUP(?)
.code
main PROC
; (insert executable instructions here)
call randomize
push OFFSET request ;passed by reference
call getData
call CrLf
push request ; passed by value
push OFFSET list ; passed by reference
call fillArray
push OFFSET list
push request
push OFFSET title_1
call displaylist
push OFFSET list
push request
call sortList
push OFFSET list
push request
call displayMedian
call CrLf
call CrLf
push OFFSET list
push request
push OFFSET title_2
call displaylist
exit ; exit to operating system
main ENDP
; (insert additional procedures here)
getData PROC
push ebp ;Set up stack frame
mov ebp, esp
;get an integer from user
mov ebx, [ebp+8] ;get address of request into ebx
L1:
mov edx, OFFSET ask_user
call WriteString
call ReadDec
cmp eax, MIN_INPUT
jl errorMessage
cmp eax, MAX_INPUT
jg errorMessage
cmp eax, MIN_INPUT
jge endThis
cmp eax, MAX_INPUT
jle endThis
errorMessage:
mov edx, OFFSET error
call WriteString
call CrLf
jmp L1
endThis:
mov [ebx], eax
pop ebp
ret 4 ; remove four more bytes from the stack (after ret @)
getData ENDP
fillArray PROC
;include parameters - request (value), array (reference)
; MAJORITY OF THE FOLLOWING CODE WAS EXTRACTED FROM LECTURE 20 SLIDES
push ebp
mov ebp, esp ;[ebp+4]
mov edi, [ebp+8] ; @list in edi
mov ecx, [ebp+12] ; value of request in ecx
more:
mov eax, HI_RANDOM
sub eax, LO_RANDOM
inc eax
call RandomRange
add eax, LO_RANDOM
mov [edi], eax
add edi, 4
loop more
endmore:
pop ebp
ret 8
fillArray ENDP
sortList PROC
push ebp
mov ebp, esp
mov edi, [ebp+12]
mov ecx, [ebp+8]
dec ecx
mov ebx, 0
firstLoop:
mov eax, ebx
mov edx, ebx
inc edx
push ecx
mov ecx, [ebp+8]
secondLoop:
mov esi, [edi + (edx * 4)]
cmp esi, [edi + (eax * 4)]
jle lesser
mov eax, edx
lesser:
inc edx
loop secondLoop
push edx
push esi
push [edi + (ebx * 4)] ; array[k]
push [edi + (eax * 4)] ; array[i]
call exchangeElements
pop [edi + (eax * 4)]
pop [edi + (ebx * 4)]
pop esi
pop edx
pop ecx ; set the
inc ebx ; increment k in the first loop
loop firstLoop
pop ebp
ret 8
sortList ENDP
exchangeElements PROC
push ebp
mov ebp, esp
mov esi, [ebp+12] ; array[k]
mov edx, [ebp+8] ; array[i]
mov [ebp+8], esi
mov [ebp+12], edx
pop ebp
ret
exchangeElements ENDP
displayMedian PROC
push ebp
mov ebp, esp ;[ebp+4]
mov edi, [ebp+12] ; @list in edi
mov ecx, [ebp+8] ; value of request in ecx
mov eax, ecx
mov ebx, 2
cdq
div ebx
cmp edx, 0
je isEven
cmp edx, 1
je isOdd
; https://github.com/TRMassey/CS271/blob/master/assignment5.asm
isEven:
; find the higher number
mov ebx, 4
mul ebx
add edi, eax
mov edx, [edi]
; find the lower number
mov eax, edi
sub eax, 4
mov edi, eax
mov eax, [edi]
; add and divide them by 2
add eax, edx
mov edx, 0
mov ebx, 2
cdq
div ebx
; print out the median value (rounded to the nearest int)
call CrLf
call CrLf
mov edx, OFFSET median
call WriteString
call WriteDec
jmp finish
isOdd:
mov eax, [edi + (eax * 4)]
call CrLf
call CrLf
mov edx, OFFSET median
call WriteString
call WriteDec
jmp finish
finish:
pop ebp
ret
displayMedian ENDP
displayList PROC
push ebp
mov ebp, esp ; [ebp+4]
mov ecx, [ebp+12] ; @request
mov edi, [ebp+16] ; @list
mov esi, 10
mov edx, [ebp+8] ; @title
call WriteString
call CrLf
show:
mov eax, [edi]
call WriteDec
mov edx, OFFSET space
call WriteString
add edi, 4
dec esi
cmp esi, 0
je callClear
loopAgain:
loop show
jmp endshow
callClear:
mov esi, 10
call CrLf
jmp loopAgain
endshow:
pop ebp
ret 12
displayList ENDP
END main
答案 0 :(得分:1)
我将继续将我的评论变成答案,以便我们结束这个问题。
我认为OP遇到的问题来自以下代码:
onChange
如您所见,ecx从mov ebx, 0
firstLoop:
mov eax, ebx
mov edx, ebx
inc edx
push ecx
mov ecx, [ebp+8]
secondLoop:
mov esi, [edi + (edx * 4)]
cmp esi, [edi + (eax * 4)]
jle lesser
mov eax, edx
lesser:
inc edx
loop secondLoop
加载。在此存储有关条目数量的用户输入。然后,代码遍历位于edi处的生成的随机数数组。
第一次执行此代码时,ebx从0开始。因此它安全地遍历了列表中的200个条目。
但是,在随后的遍历中,ebx可以大于0。但是,ecx仍然是200。因此,我们仍然要遍历200个条目,但是我们不再从索引0开始。
这意味着,我们正在读/写超出分配空间的末尾。这就是为什么输出为垃圾的原因。
这似乎适用于较少数量的条目的原因是列表的空间已预先分配(显然是零填充?)。由于排序是“降序”的,因此所有零看起来都不需要移动。
虽然我还没有从头到尾都进行过追踪,但至少这将是一个问题。
在[ebp+8]
之后添加sub ecx, ebx
的简单解决方法似乎可以解决问题。