我在汇编语言课程中,我们正在进行练习,我们需要在堆栈上传递参数,以便在特定范围内生成 n 随机数。
我遇到的问题:
我的随机数不在我指定的范围内
2.当我返回此数组并尝试对其进行排序并再次显示时,该数组将填充不同的值。
我认为这些问题在某种程度上与我传递参数的方式有关。
TITLE Program 4 (Project04.asm)
INCLUDE Irvine32.inc
.data
intro_1 BYTE "Composite Numbers Programmed by ",0
prompt_1 BYTE "This program generates random numbers in the range [100 .. 999],",0
prompt_2 BYTE "displays the original list, sorts the list, and calculates the ",0
prompt_3 BYTE "median value. Finally, it displays the list sorted in descending order.",0
prompt_4 BYTE "How many numbers should be generated? [10 .. 200]: ",0
space3 BYTE " ",0
errorMessage BYTE "Invalid input ",0
userNum DWORD ?
min = 10
max = 200
lo = 100
hi = 999
array DWORD max DUP(?)
.code
main PROC
call Introduction
push OFFSET userNum
call getData
;call Randomize
push OFFSET array
push userNum
call fillArray1
push OFFSET array
push userNum
call displayList
call crlf
call crlf
push OFFSET array
push userNum
call sortList
push OFFSET array
push userNum
call displayList
exit
main ENDP
Introduction PROC
mov edx, OFFSET intro_1
call WriteString
call crlf
mov edx, OFFSET prompt_1
call WriteString
call crlf
mov edx, OFFSET prompt_2
call WriteString
call crlf
mov edx, OFFSET prompt_3
call WriteString
call crlf
call crlf
ret
Introduction ENDP
;Get Data
getData PROC
getUserData:
push ebp
mov ebp, esp
mov edx, OFFSET prompt_4
call WriteString
call ReadInt
mov userNum, eax
;call crlf
;validate
cmp eax, max
ja error1
cmp eax, min
jb error1
pop ebp
ret
error1:
mov edx, OFFSET errorMessage
call WriteString
call crlf
jmp getUserData
getData ENDP
;Fill array
fillArray1 PROC
fillArray:
push ebp
mov ebp,esp
pushad ; save registers
mov esi,[ebp+12] ; offset of array
mov ecx,[ebp+8] ; array size
cmp ecx,0 ; ECX == 0?
je L2 ; yes: skip over loop
mov edx, hi
sub edx, lo
L1:
mov eax, edx
call RandomRange ; from the link library
add eax, lo
mov [esi], eax
add esi, 4
loop L1
L2:
popad ; restore registers
pop ebp
ret 8 ; clean up the stack
fillArray1 ENDP
;Sort List
sortList PROC
push ebp
mov ebp, esp
mov ecx, [ebp + 8]
dec ecx ; decrement count by 1
L1:
push ecx ; save outer loop count
mov esi, [ebp + 12] ; point to first value
L2:
mov eax,[esi] ; get array value
cmp [esi+4],eax ; compare a pair of values
jge L3 ; if [esi] <= [edi], don't exch
xchg eax,[esi+4] ; exchange the pair
mov [esi],eax
L3:
add esi,4 ; move both pointers forward
loop L2 ; inner loop
pop ecx ; retrieve outer loop count
loop L1 ; else repeat outer loop
L4 :
pop ebp
ret 8
sortList ENDP
;Display Median
displayMedian PROC
displayMedian ENDP
我认为我的fillArray程序中的返回值可能已关闭?
displayList程序:
;Display list
displayList PROC
push ebp
mov ebp, esp
mov ecx, [ebp + 8]
jecxz farewell
mov esi, [ebp + 12] ;set counter for the linebreak
Print:
mov eax, [ebx]
call WriteDec
dec esi
jnz Spaces
linebreak:
call crlf
mov esi, 10
jmp Next
Spaces:
cmp esi, 0 ;if there has been ten elements, go to next line
je linebreak
mov edx, OFFSET space3
call WriteString
Next:
add ebx, 4
loop Print
pop ebp
ret 8
displayList ENDP
接受引用参数的getData过程:
;Get Data
getData PROC
push ebp
mov ebp, esp
pushad
mov esi, [ebp + 8] ;move the address of the userNum
getUserData:
mov edx, OFFSET prompt_4
call WriteString
call ReadInt
mov userNum, eax
mov esi, userNum ;move the userNum to the address
;call crlf
;validate
cmp eax, max
ja error1
cmp eax, min
jb error1
pop ebp
ret
error1:
mov edx, OFFSET errorMessage
call WriteString
call crlf
jmp getUserData
getData ENDP
当我进行此更改时,在输入要打印的随机数后,程序崩溃。
答案 0 :(得分:0)
fillArray
和sortList
工作正常,我已对其进行了测试。
getData
在error1
路径中有一个错误(确实很大),在打印错误消息后,您跳回getUserData
再次创建堆栈帧。
将此创作移到getUserData
标签上方,getData
下方。
Introduction
应该正常工作(未经过严格测试)。
main
程序存在一些问题:
call Introduction ;OK
push OFFSET userNum
call getData ;getData takes no params
;Either update getData (don't forget ret 04h)
;or remove the push
;call Randomize
push OFFSET array
push userNum
call fillArray1 ;This should work
push OFFSET array
push userNum
call displayList ;Don't know, no code for displayList
call crlf
call crlf
push OFFSET array
push userNum
call sortList ;This should work
;push OFFSET array ;<-- This is commented
push userNum
call displayList ;!! You are not passing the array to display
;That's why you will see different values
在重构其他功能后,您似乎忘记更新main
。
displayList
程序似乎错了,因为:
ebx
esi
将保存数组指针,但您似乎将其用作计数器farewell
未在任何地方定义我认为这个新的displayList
可能有用(请,请注意,我甚至没有编译它,我没有NASM,也没有计划安装)
;Array
;Number of elements
;Elements per line
displayList PROC
push ebp
mov ebp, esp
push esi
push ecx
push edx
mov esi, [ebp + 16] ;Array
mov ecx, [ebp + 12] ;Items in array
PrePrint:
mov edx, [ebp + 8] ;Counter for linebreaks
Print:
jecxz End
lodsd
call WriteDec ;Print items
mov edx, OFFSET space3
call WriteString ;Print space
dec ecx
dec edx
jnz Print
call crlf
jmp PrePrint
End:
pop edx
pop ecx
pop esi
pop ebp
ret 12
displayList ENDP
注意这个新的displayList
需要 3 个参数:
push OFFSET array
push userNum
push 10 ;Items per line
call displayList
如果您想对每行的项目进行硬编码并删除过去的参数,请编辑该功能,请记得更新ret 12
和[ebp + xx]
引用!
在新的getData
中,您忘记在popad
之前执行pop ebp
,并将ret
替换为ret 04h
。