MASM计算复合材料

时间:2015-07-14 21:24:31

标签: assembly masm

我正在尝试运行代码,要求用户输入1到400之间的输入并提供该数量的复合。防爆。输入31将产生 4 6 8 9 10 12 14 15 16 18 20 21 22 24 25 26 27 28 30 32 33 34 35 36 38 39 40 42 44 45 46

尝试运行时,以下代码崩溃:

        userInt1    DWORD   ?           ;integer to be entered by user
    userInt2    DWORD   ?           ;integer to be entered by user
    intro_1     BYTE    "Composite Numbers  by. Eric Walters" , 0
    prompt_1    BYTE    "Enter the number of composite numbers you would like to see. ", 0
    prompt_2    BYTE    "I'll accept orders for up to 400 composites. ", 0
    prompt_3    BYTE    "Enter the number of composites to display [1 .. 400]: ", 0
    prompt_4    BYTE    "Test", 0
    prompt_6    BYTE    "Results certified by Eric Walters.",0
    prompt_7    BYTE    "Goodbye, ", 0
    outOfRange  BYTE    "Out of range. Try again.",0
    goodBye     BYTE    "Impressed? Bye! ", 0
    upperLevel  DWORD   400         ;the largest integer allowed
    lowerLevel  DWORD   1           ;the smallest integer allowed
    newArray    DWORD   500 DUP(?)


.code
main PROC

push    OFFSET newArray
push    ebp
mov     ebp,esp
mov     esi,[ebp + 8]


; Introduction  

    mov     edx, OFFSET intro_1
    call    WriteString
    call    CrLf
    call    CrLf
    mov     edx, OFFSET prompt_1
    call    WriteString
    call    CrLf
    mov     edx, OFFSET prompt_2
    call    WriteString
    call    CrLf
    call    CrLf

; getUserData
    userPrompt:
        mov     edx, OFFSET prompt_3
        call    WriteString
        call    ReadInt
        mov     userInt1, eax
        mov     eax, userInt1

    ;validate   
        cmp     eax, upperLevel
        ja      option1
        cmp     eax, lowerLevel
        jb      option1
        jmp     option2

    option1 :
        mov     edx, OFFSET outOfRange
        call    WriteString
        call    crlf
        jmp     userPrompt

    mov     ecx, 4
    option2 :
        cmp     ecx, userInt1
        jnle    done
        mov     ebx, 2  

    showComposites :
        mov     edx, ecx
        sub     edx, 1
        cmp     ebx, edx
        jge     L1
        mov     eax, ecx
        div     ebx
        cmp     edx, 0
        je      composite

    resume :
        inc     ebx
        jmp     showComposites

    L1:
        inc     ecx
        jmp     option2

    done :
        pop     ebp
        ret     4

    composite:
        mov     [esi], ecx
        add     esi, TYPE DWORD
        jmp     L1

; farewell
    mov     edx, OFFSET prompt_6
    call    WriteString
    call    crlf
    mov     edx, OFFSET prompt_7
    call    WriteString
    call    crlf


    exit        ; exit to operating system
main ENDP

END main

非常感谢任何帮助!

2 个答案:

答案 0 :(得分:0)

假设你没有组装一个exe,所以你的EXTRN / PUBLIC声明是有序的。

jmp     userPrompt

mov     ecx, 4           ;Useless code?

option2 :
cmp     ecx, userInt1    ;Not understanding when ECX is initialized and
jnle    done             ;why, was it suppose to be the above code
mov     ebx, 2           ;that is misplaced?

这部分让我失望了,现在我不理解顺序复合数的算法。

这是一个想法:为什么不只是设置一个1-400个复合数字的数组,让1-400之间的用户输入成为一个循环计数器,显示每个数组元素? (虽然在时间和内存上效率不如优秀的算法。)

答案 1 :(得分:0)

我没有运行你的代码,我想说实话:我讨厌NASM以及所有它的高级指令和宏。

我最好的猜测是这个

    push    OFFSET newArray
    push    ebp
    mov     ebp,esp
    mov     esi,[ebp + 8]

    ;Whole lotta stuff

done:
    pop     ebp
    ret     4

也许你是复制粘贴代码,我不知道,但这会将 main proc的返回地址设置为newArray的地址,并在返回时崩溃。登记/> 我看到你是如何尝试将数组作为参数传递的,但是没有你调用的函数。

除了Nhat M Le在其答案中突出显示的点之外,其余代码应该可以工作或需要进行微调(请注意,我没有运行它)。

我可以给你一些建议吗?

<强> 1。给出算法和问题的描述

当您发布代码,特别是汇编代码时,请提供您正在实施的算法的一般说明。

特别是当存在一系列算法的空间时:从初学者使用试验分区到polynomial time primality test的更一般版本,通过切割器并直观地使用sieve < / p>

此外,还包括您面临的具体问题。

这有助于我们识别问题,而不会试图深入思考并阅读许多可能非常破碎的代码。

<强> 2。相应地命名您的变量

您是否真的使用userInt1而不是upperLimitdwUpperLimitui32UpperLimit

第3。已知您的数据大小

努力识别哪些数据应该在运行时占用内存空间,哪些不应该占用空间 upperLevellowerLevel最好用EQU(或任何MASM等价物)声明。

如果您最多支持400个数字,为​​什么要为数组分配500个DWORD? 我可能遗漏了一些东西但是在我没有的情况下,这可能是一种懒惰或不是编程态度的症状,如果你对编程感兴趣就摆脱它。

我不希望您知道如何正确使用pi(x) function和估算技术,但最多需要400个DWORD(Pro-tip:与点2 EQU合并使用)。

<强> 4。使用函数

将问题划分为子问题

这确实有助于调试和防止装配错误。

<强> 5。缩进代码并保持清晰

汇编代码没有缩进规则,但作为人类,我们会自动找到一种乐趣阅读的风格。

请记住在逻辑上区分不同的代码片段,你做一些标题注释,但整个循环逻辑搞砸了,如果你继续编程,你会发现你可以编写非常清晰的代码,即使有多个跳转

所有这些只是为了制作笑话并回答数据问题

goodBye     BYTE    "Impressed? Bye! ", 0

带有数据回答

strGoodBye db "Not very much :)", 0