有人可以解释我需要在这个80x86汇编程序中改变什么吗?

时间:2014-04-24 02:20:28

标签: assembly parameters x86 stack greatest-common-divisor

以下是代码:

.586
.MODEL FLAT

INCLUDE io.h                ; header file for input/output

.STACK 4096

.DATA
prompt1 BYTE    "Enter n1", 0
prompt2 BYTE    "Enter n2", 0
n1 dword ?
n2 dword ?
gcdp dword ?
remp dword ?

string  BYTE    40 DUP (?)  
resultLbl BYTE  "gcd is:",0 

.CODE
_MainProc   PROC
        input prompt1, string, 40   
        atod string             
        mov n1, eax

        input prompt1, string, 40   
        atod string             
        mov n2, eax

        push n2
        push n1
        call gcd
        add esp, 8

        dtoa string, eax
        output resultLbl, string

        mov eax, 0
        ret
_MainProc   ENDP

gcd PROC
        push ebp
        mov ebp, esp
        push n2
        push n1
        mov eax, n1
        mov gcdp, eax
        mov eax, n2
        mov remp, eax

   L1:  mov eax, gcdp
        cdq
        idiv remp
        mov ebx, remp
        mov gcdp, ebx
        mov remp, edx
        cmp edx, 0
        jnz L1

        mov eax, gcdp

        pop ebx
        pop edx
        pop ebp
        ret
gcd ENDP

END

问题就在这里(正如我老师所说): "缺少从堆栈中读取参数。请确保你正在用字节ptr [ebp + 8]和字节ptr [ebp + 12]读n2和n1,你也不必在程序中按n1,n2和pop n1n2。其余的看起来很好。"

那么......是什么?什么需要改变,什么是多余的?

1 个答案:

答案 0 :(得分:0)

  

需要改变什么以及什么是多余的?

不需要这些全局变量:

n1 dword ?
n2 dword ?
gcdp dword ?
remp dword ?

使用寄存器代替。还可以将string移出.data部分(已初始化的数据)并移至.data?部分(未初始化的数据):

.DATA
prompt1     BYTE "Enter n1", 0
prompt2     BYTE "Enter n2", 0
resultLbl   BYTE "gcd is:",0 

.data?
string      BYTE 40 DUP (?) 

.CODE
_MainProc   PROC

    input   prompt1, string, 40     
    atodw   string             
    mov     esi, eax

    input   prompt1, string, 40     
    atod    string             
    mov     edi, eax

    push    edi
    push    esi
    call    gcd
    add     esp, 8

    dtoa    string, eax
    output  resultLbl, string

    mov     eax, 0
    ret
_MainProc   ENDP

gcd PROC
    push    esi
    push    edi
    push    ebx

    mov     esi, [esp + 16] ;n1
    mov     edi, [esp + 20] ;n2

L1:  
    mov     eax, esi
    cdq
    idiv    edi
    mov     ebx, edi
    mov     esi, ebx
    mov     edi, edx
    cmp     edx, 0
    jnz     L1

    mov     eax, esi

    pop     ebx
    pop     edi
    pop     esi
    ret
gcd ENDP

END _MainProc

我们“技术上”不必在esi proc中保存ediebxgcd,因为外部不会与我们的代码接口,但是让我们学习正确的开始方式。如果我们不保存这些寄存器,则参数将位于[esp + 4][esp + 8]。我们也可以获得一些提升并摆脱string全局变量,只需使用堆栈来保存字符串。