在MASM程序集中加密到后缀转换

时间:2017-06-11 17:52:25

标签: assembly x86 masm

这是我使用MASM从输入文件中简单计算内容的任务。我们使用的书是“x86处理器的汇编语言”。

现在我正在尝试使用中缀进行后缀转换。我尝试转换的输入是:12/3+4,但它刚刚停止并显示.exe已停止工作,我发现它停在主函数的INVOKE CheckAddSub处。

你能帮我看看那个过程中出了什么问题吗?我曾尝试使用stack来推送/弹出但后来我改为使用,因为我正在调用函数,我认为不使用堆栈会更容易。非常感谢您花时间查看我的代码。

INCLUDE C:\Irvine\Irvine32.inc
INCLUDE C:\Irvine\macros.inc
CheckAddSub PROTO, seStr1:PTR BYTE, outStr1:PTR BYTE, pCo:DWORD, pDo:DWORD, 
outCo1:DWORD
CheckMulDiv PROTO, seStr2:PTR BYTE, outStr2:PTR BYTE, theCo:DWORD, 
theDo:DWORD, outCo2:DWORD

.data
inputStr BYTE 20 dup(?)    ;input array
outputStr BYTE 20 dup(?)   ;postfix array
sizeSt DWORD 20
secStr BYTE 10 dup(?)    ;to store the operator
count DWORD 0
dStr BYTE 0
outCount DWORD 0

.code
main PROC
    mWrite "Input: "
    mov edx, OFFSET inputStr 
    mov ecx, SIZEOF inputStr - 1
    call ReadString
    mov esi, OFFSET inputStr     ;now the input str has elements
    mov edi, OFFSET outputStr    ;for storing the postfix 
    mov ecx, sizeSt              ;to loop
    mov edx, OFFSET secStr       ;to store operator

L1:
    mov ebx, [esi]
    .if bl=='+'|| bl=='-' 
        inc count             

    .if count > 1           ;when count is 2 mean there is already element in 
                             the secStr array so i can do the checking
        INVOKE CheckAddSub, ADDR secStr, ADDR outputStr, count, dStr,outCount
        inc dStr        ;dStr is to store the index number of the secStr 
                         array, after the zero index predencency is checked, 
                        ;increment dStr to indicate the index number this 
                         current operator in secStr array

    .endif

    mov [edx],ebx     ;put the operator into secStr
    add edx,1

    .elseif bl=='*'|| bl =='/'
        inc count

    .if count > 1
        INVOKE CheckMulDiv, ADDR secStr, ADDR outputStr , count, dStr, outCount
        inc dStr
    .endif

    mov [edx],ebx   
    add edx,1

    .else                  ;when it is operand(number), put into output array
       mov [edi], ebx
       inc outCount
    .endif

    inc edi
    inc esi
    dec ecx  
    cmp ecx,0
    jne L1    

    mov edx, OFFSET outputStr
    mWrite "the postfix string is: "
    call WriteString

   INVOKE ExitProcess,0

 main ENDP
 ;-----------------------------------------------------------
 CheckAddSub PROC USES edx edi eax ecx ebx,
 seStr1:PTR BYTE,      ;secStr
 outStr1:PTR BYTE,     ;outputStr
 pCo:DWORD, 
 pDo:DWORD,
 outCo1:DWORD
;------------------------------------------------------------

    mov edx, seStr1      
    mov edi, outStr1

LW:
    mov ebx, [edx+pDo]            ;edx+pDo is the last element in the array, 
                                     like stack the top element
    .if bl=='+'|| bl=='-'|| bl=='*' || bl=='/'
         mov [edi+outCo1],ebx      ;if one of these operator exists in the 
                                    secStr array, then put this operator into 
                                    the outputStr array 
         mov [edx+pDo], 0          ;put null in this current index,indicating 
                                    this element is already pop out from the 
                                    secStr array    
         inc outCo1 
    .endif

    .if pDo!=0
         sub pDo,1
    .endif

    dec pCo         
    cmp pCo,1
    jne LW
    je L5

L5: ret 

CheckAddSub ENDP

;------------------------------------------------------
CheckMulDiv PROC USES edx edi eax ecx ebx,
  seStr2:PTR BYTE, 
  outStr2:PTR BYTE, 
  theCo:DWORD, 
  theDo:DWORD,
  outCo2:DWORD
;-------------------------------------------------------

   mov edx, seStr2
   mov edi, outStr2

LR:
   mov ebx,[edx+theDo]
   .if bl=='*'|| bl=='/'
      mov [edi+outCo2],ebx
      mov [edx+theDo],0
      inc outCo2
   .endif

   .if theDo!=0
     sub theDo,1
   .endif

   dec theCo
   cmp theCo, 1
   jne LR
   je L6

L6: ret

CheckMulDiv ENDP
END main

1 个答案:

答案 0 :(得分:2)

call ReadString
mov esi, OFFSET inputStr     ;now the input str has elements
mov edi, OFFSET outputStr    ;for storing the postfix 
mov ecx, sizeSt              ;to loop

您正在使用固定数量的迭代。在这种情况下,20,因为 sizeSt 是这样定义的。

你想要的是迭代你实际收到的字节。您从 ReadString 中获得了EAX的计数,因此请使用它:

call ReadString
mov esi, OFFSET inputStr     ;now the input str has elements
mov edi, OFFSET outputStr    ;for storing the postfix 
mov ecx, eax                 ;to loop
mov ebx, [esi]
...
mov [edx], ebx
...
mov [edi], ebx

由于您正在处理字节,因此必须使用字节大小的BL寄存器而不是DWORD大小的EBX寄存器!

dStr BYTE 0

考虑PROTO / INVOKE,您需要将其更改为:

dStr DWORD 0