【问题标题】:Can someone explain what I need to change in this 80x86 assembly program?有人可以解释我需要在这个 80x86 汇编程序中更改什么吗?
【发布时间】:2014-06-09 03:12:13
【问题描述】:

代码如下:

.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在程序中。其余的看起来都很好。”

那么……怎么了?什么需要改变,什么是多余的?

【问题讨论】:

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


    【解决方案1】:

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

    不需要这些全局变量:

    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
    

    我们“技术上”不必在gcd proc 中保存esiediebx,因为没有任何外部可以与我们的代码交互,但让我们学习正确的开始方式.如果我们不保存这些寄存器,那么参数将位于[esp + 4][esp + 8]。我们还可以稍微进阶一点,去掉string 全局变量,只使用堆栈来保存字符串。

    【讨论】:

      猜你喜欢
      • 2012-10-26
      • 1970-01-01
      • 2010-12-17
      • 2014-12-06
      • 1970-01-01
      • 2011-06-09
      • 2021-02-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多