x86 彙編程序崩潰,可能忽略了簡單的錯誤 (x86 assembly procedure crashes, possibly overlooking simple error)


問題描述

x86 彙編程序崩潰,可能忽略了簡單的錯誤 (x86 assembly procedure crashes, possibly overlooking simple error)

Hello this is my first time posting here, but I am working on a homework assignment that is to design an assembly function syracuse(N, sequence) with these given rules:  1. if N is 1, end loop.  2. if N is even, then N=N/2, goto beginning of loop 3. if N is odd, then N= 3N+1, goto beginning of loop

Pretty simple, then he wants us to display some information and create a report. However, I have been staring at this code for several hours now and I cannot figure out what is wrong. Once I comment out the call, the program works great and will not crash, otherwise it will crash. I think I am just overlooking something simple and fundamental, could any of you provide assistance? 

Here is the code:

.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

參考解法

方法 1:

Your best bet is to use a debugger and step through your assembly.  However, a few things leap out at me:

array isn't an array, it's just an uninitialized DWORD.

push n  
push array

This is backwards based on how syracuse accesses its arguments.  Generally, your calling convention would be right‑to‑left in push order.  If array is pushed first, its value would be at EBP+12 and n would be at EBP+8.

mov [esi+4], eax

ESI = EBP+12.  Therefore, [ESI+4] = [EBP+16] and that stack location likely stores the return address of start's caller; probably not a good idea to change it.  Since array isn't really an array and you're writing to the same location each time, you probably can skip using ESI altogether and use mov [ebp+12], eax instead (although you seem to be discarding the value entirely; perhaps you wanted to push the address of array onto the stack?).

idiv ebx

The idiv instruction divides the 64‑bit integer EDX:EAX by the operand EBX, in this case.  Since you don't clear EDX, you may not get the result you desire (including integer overflow exceptions).  Try a xor edx, edx before the idiv.

I didn't really check to see if all of your logic is correct, just saw the above issues.

(by James LittlePeter Huene)

參考文件

  1. x86 assembly procedure crashes, possibly overlooking simple error (CC BY‑SA 3.0/4.0)

#intel #assembly #x86






相關問題

x86 彙編程序崩潰,可能忽略了簡單的錯誤 (x86 assembly procedure crashes, possibly overlooking simple error)

英特爾虛擬化問題 (Android Studio) (Intel Virtualization Problems (Android Studio))

Intel 芯片組 - GPIO 編程 (Intel chipset - GPIO programming)

如何編譯 gcc 、 intel 靜態庫? (How to compile wth gcc , intel static libraries?)

我們可以在 OpenWrt linux 操作系統上運行 DPDK 應用程序嗎? (Can we run DPDK application on OpenWrt linux os?)

如何將內存中的 96 位加載到 XMM 寄存器中? (How to load 96 bits from memory into an XMM register?)

英特爾 PIN 二進制檢測工具中的 16 個通用寄存器如何表示 (How are the 16 General Purpose Registers represented in Intel PIN binary instrumentation tool)

Delphi 的 x86 代碼生成器框架 (x86 code generator framework for Delphi)

處理器:如何獲取有關英特爾至強的緩存信息 (Processor : How to get cache information about intel xeon)

任何人都試圖為另一個操作系統編譯 Intel xf86_video_intel (Anyone tried to compile Intel xf86_video_intel for another OS)

飛地字段不工作,但沒有錯誤 (Enclave field not working, but there is no error)

是否可以在 Intel SDE 中結合 CPUID 和指令集仿真參數 (Is it possible to combine CPUID and Instruction set emulation arguments in Intel SDE)







留言討論