Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly x86汇编过程崩溃,可能忽略了简单错误_Assembly_X86_Intel - Fatal编程技术网

Assembly x86汇编过程崩溃,可能忽略了简单错误

Assembly x86汇编过程崩溃,可能忽略了简单错误,assembly,x86,intel,Assembly,X86,Intel,您好,这是我第一次在这里发帖,但我正在做一个家庭作业,就是用这些给定的规则设计一个汇编函数syracuse(N,序列): 1.如果N为1,则结束循环。 2.若N为偶数,则N=N/2,转到循环的开头 3.若N为奇数,则N=3N+1,转到循环的开头 非常简单,然后他希望我们显示一些信息并创建一个报告。然而,我已经盯着这段代码看了好几个小时了,我不知道到底出了什么问题。一旦我对调用进行了注释,程序运行良好,不会崩溃,否则它会崩溃。我想我只是忽略了一些简单而基本的东西,你们能提供帮助吗 代码如下: .5

您好,这是我第一次在这里发帖,但我正在做一个家庭作业,就是用这些给定的规则设计一个汇编函数syracuse(N,序列): 1.如果N为1,则结束循环。 2.若N为偶数,则N=N/2,转到循环的开头 3.若N为奇数,则N=3N+1,转到循环的开头

非常简单,然后他希望我们显示一些信息并创建一个报告。然而,我已经盯着这段代码看了好几个小时了,我不知道到底出了什么问题。一旦我对调用进行了注释,程序运行良好,不会崩溃,否则它会崩溃。我想我只是忽略了一些简单而基本的东西,你们能提供帮助吗

代码如下:

.586
.MODEL FLAT
INCLUDE io.h   
cr  EQU 0dh;carriage return
Lf  EQU 0ah;line feed 
.STACK  4096
.DATA
array   DWORD ?
n       DWORD   0
steps   DWORD   0   
prompt  BYTE    "Enter N: ", 0
count   BYTE    cr, Lf, "Total Numbers: "
string  BYTE    40 DUP (?)
result  BYTE    cr, Lf, "N: "

;result2    BYTE    cr, Lf, "Steps: "
lbl BYTE 11 DUP (?)
BYTE cr, Lf, 0
.CODE
_start    PROC
    output prompt ;ask for n
    input string, 40
    atod string ; convert to int
    mov n, eax  
    dtoa lbl, n ;convert to ascii
    output result; print out n

    push n
    push array
    call syracuse
    add esp, 8
    ret
_start    ENDP
syracuse PROC ; syracuse(n, array)
    push ebp
    mov ebp, esp
    push ebx;save ebx
    push eax;save eax
    push esi
    mov eax, [ebp+8] ;first parameter 
    lea esi, [ebp+12] ;beginning of the array
            mov ecx, 0
    whileLoop:  inc ecx; ecx++
                mov [esi+4], eax
                cmp eax, 1
                je endLoop ;if n = 1, then end
                mov ebx, 2
                idiv ebx
                cmp edx, 0
                je evenProc ; if n is even

                ;if n is odd then 3N + 1
                shl eax, 1
                add eax, 2
                jmp whileLoop               
    evenProc: ;if n is even then N = N/2
        mov ebx, 2
        idiv eax
        jmp whileLoop
    endLoop:
        dtoa lbl, ecx
        output count;display count
        pop esi
        pop eax
        pop ebx
        pop ebp
        ret

syracuse ENDP
END

最好的方法是使用调试器并逐步完成程序集。然而,我突然想到了几件事:

array
不是数组,它只是一个未初始化的DWORD

push n  
push array
这是基于
syracuse
访问其参数的方式向后的。通常,您的呼叫约定是按推送顺序从右向左。若首先推送数组,它的值将在EBP+12,n将在EBP+8

mov [esi+4], eax
ESI=EBP+12。因此,[ESI+4]=[EBP+16],该堆栈位置可能存储start调用方的返回地址;改变它可能不是个好主意。由于
array
实际上不是一个数组,并且每次都要写入相同的位置,因此您可能可以完全跳过使用ESI,而改用
mov[ebp+12],eax
(尽管您似乎完全放弃了该值;也许您想将
array
的地址推到堆栈上?)

在本例中,idiv指令将64位整数EDX:EAX除以操作数EBX。由于未清除EDX,因此可能无法获得所需的结果(包括整数溢出异常)。在
idiv
之前尝试异或edx,edx


我没有真正检查您的逻辑是否正确,只是看到了上面的问题。

您解决了我的崩溃问题!非常感谢你的帮助,不要因为我犯了愚蠢的错误而责骂我@如果答案解决了你的问题,确保你接受它!
idiv ebx