【发布时间】:2023-03-23 16:37:01
【问题描述】:
我必须编写一个汇编程序,该程序将调用一个外部汇编文件来生成用户指定的素数数量。现在我想生成小于 10 的素数,然后将其报告回屏幕,稍后再担心用户输入。 genprimes.asm 中的代码将正确生成素数并将它们存储到数组中。我想将它们压入堆栈(参见 genprimes.asm 中的第 79 行),并在调用 seive.asm 中的该函数返回后恢复它们。如果我注释掉“push ecx;”,我的代码在 genprimes.asm 中有效在第 79 行。 sieve.asm 在第 32 行中断,这是代码“调用 genPrimes”。我尝试单步执行“genprimes.asm”中的所有代码,然后进入 return 语句,然后 Visual Studio 说我无法进一步调试,因为它不支持跳回主文件。我不知道为什么会这样。我怎样才能让我的素数回到我称之为“genprimes.asm”的主文件“sieve.asm”?
筛子.asm:
.586
.MODEL FLAT
INCLUDE io.h
EXTERN GenPrimes2:PROC
PUBLIC genPrimes
.STACK 4096 ; reserve 4096-byte stack
.DATA ; reserve storage for data
count DWORD ?
sieve BYTE 10000 DUP(1)
string BYTE 40 DUP (?)
prompt1 BYTE "Enter number of primes: ", 0
prompt2 BYTE "prime number: ", 0
primenum BYTE 11 DUP (?), 0
.CODE
genPrimes PROC
; push ebp ; save base pointer
; mov ebp, esp ; establish stack frame
; push ebx
; CODE
call GenPrimes2 ;*** breaks here ***
; pop ebx
; pop ebp
ret ;exit genPrimes
genPrimes ENDP
_sieve PROC ; start of sieve program code
input prompt1, string, 40 ; read ASCII characters
call genPrimes
output prompt2, primenum ; output label and sum
mov eax, 0 ; exit with return code 0
ret
_sieve ENDP
END
genprimes.asm:
.586
.MODEL FLAT
.STACK 4096
n=10
.data
prime DWORD n DUP(?)
.code
GenPrimes2 PROC
mov ebx, 4
mov ecx, 0
loopArray:
inc ecx
mov prime[ebx], ecx
add ebx, 4
cmp ecx, n
jb loopArray
mov eax, 3
mov ebx, 2
mov edx, 0
mov ecx,3
sieve_loop:
cmp eax,ebx
je skip
mov edx, 0 ;zero out remainder
div ebx
cmp edx,0 ; if remainder 0, not a prime
je NotPrime ;Jump if is a factor, since it cant be prime
; compare eax with n, if equal increment ebx
cmp ecx,n
jge incrementEbx
; compare ebx with n, if equal end sieve
cmp ebx, n
je sieve_end
inc ecx
mov eax, ecx
jmp sieve_loop
skip:
inc eax
jmp sieve_loop
NotPrime:
mov eax, ecx ; store count in eax
imul ecx, 4
mov prime[ecx],0
mov ecx, eax
inc ecx ; increment ecx count
inc eax ; increment eax divisor
jmp sieve_loop
incrementEbx:
inc ebx
mov eax, 3 ; dividend
mov ecx, 3 ; counter
jmp sieve_loop
sieve_end:
mov ebx, 4
mov eax, 0
; ************* Add break point on print loop, ecx will be loading with primes and 0's ********************
; ************* All non-prime numbers have been changed to a 0 ********************
PrintLoop:
mov ecx, prime[ebx] ; Prime numbers are the non-zeros in this Array
push ecx ; **This is somehow breaking it, but doesnt throw and error
;** when steeping through in Visual Studio?!?
add ebx, 4
cmp ebx, 40
jb PrintLoop
mov eax, 0 ; exit with return code 0
ret
GenPrimes2 ENDP
END
【问题讨论】:
-
不,我将代码粘贴到记事本++中以获取行数。它的代码调用“GenPrimes2 ;*** 在此处中断 ***” 这意味着错误应该在 genprimes.asm 中?所以我在文件中放了一个断点,它没有中断,一直到返回语句。 Visual Studio 不会让我使用 return 语句跳回来。所以我无法确定它为什么会破裂。我认为这是我如何在代码底部的循环中将值推送到 genprimes.asm 中的堆栈。如果我将其注释掉,我不会收到任何错误,但我可以使用调试功能逐步完成循环而不会出错
标签: x86