2016-11-19 29 views
1

所以我想讓一個用戶輸入一個字符串,並且我需要保留字母在用戶字符串中的出現次數。防爆。 「你好」H = 1,e = 1,l = 2,依此類推。將BYTE參數傳遞給使用INVOKE MASM的過程

但是,我無法將大小爲BYTE的指針和字符串的最大長度爲132個字符傳遞給我的過程GetNumLetters。

當我得到的字符串的長度爲例如「你好」stringLength = 5但是當我將stringLength傳遞給我的過程存儲該值(arrayLength)的參數不等於5,但是像一些瘋狂的數字8398473 。我只是不明白爲什麼arrayLength不等於5當我將stringLength傳遞給函數GetNumLetters。 (我沒有測試過其餘的函數,因爲我無法獲得字符串的大小)。

我的想法是,stringLength傳遞8位和其他24位隨機填充。但是,我不知道在這種情況下,我會如何填充類型轉換字符串長度爲32位,高位24位= 0。

INCLUDE Irvine32.inc 

INCLUDE Macros.inc 

GetNumLetters PROTO, arrayInput: PTR BYTE, arrayCount: PTR BYTE, arrayLength: BYTE 
PrintNumLetters PROTO, arrayCount: PTR BYTE, arrayLength: BYTE 

.data 

charInput BYTE 132 DUP (?) ;an array that stores the users input of 132 values 

charCount BYTE 123 DUP (0)  ;an array to store the instances of letters ONLY CARE ABOUT ASCII CHAR A-Z,a-z,0-9 

stringLength BYTE 0    ;length of the string 

msg BYTE "Enter String: ",0 


.code 
main proc 

    xor edx, edx 
    xor eax, eax 
    xor ecx, ecx 
    mov edx, OFFSET msg 
    Call WriteString 
    mov edx, OFFSET charInput ;point to buffer you want input stored 
    mov ecx, SIZEOF charInput ;specify length of string 
    call ReadString    ;get string from user 
    mov stringLength, BYTE PTR eax ;make 32bit to 8bit 


    INVOKE GetNumLetters, OFFSET charInput, OFFSET charCount, stringLength 

    exit 
main ENDP 

;========================================================================== 

GetNumLetters PROC, arrayInput: PTR BYTE, arrayCount: PTR BYTE, arrayLength: BYTE 
    ;might need to put arrayInput and arrayCount into esi edi 
    push ecx 
    push eax 
    push ebp 
    mov ebp, esp 
    xor ecx, ecx 
    xor eax, eax 
    movzx ecx, arrayLength 

    movzx eax, arrayLength 
    call WriteDec 

    ;check for letters 0-9 
    LoopG1: 
      mov eax, DWORD PTR [arrayInput + ecx] 
      dec ecx       ;decrease loop counter 
      cmp eax, 48      ;check if eax < 0 
      jb LoopG1      ; if eax < 0 try another letter 
      cmp eax, 57      ;check if eax > 9 
      ja LoopG1      ; if eax > 9 try another letter 
      inc DWORD PTR [arrayCount + eax]   ;increment the letter's count 
      jmp LoopG1 

    xor ecx, ecx 
    mov ecx, DWORD PTR arrayLength 
    ;check for letters A-Z 
    LoopG2: 
      mov eax, DWORD PTR [arrayInput + ecx] 
      dec ecx       ;decrease loop counter 
      cmp eax, 65      ;check if eax is < A 
      jb LoopG2      ; if eax < A try another letter 
      cmp eax, 90      ;else check if eax > Z 
      ja LoopG2      ; if eax > Z try another letter 
      inc DWORD PTR [arrayCount + eax]   ;increment the letter's count 
      jmp LoopG2 

    xor ecx, ecx 
    mov ecx, DWORD PTR arrayLength 
    ;check for letters a-z 
    LoopG3: 
      mov eax, DWORD PTR [arrayInput + ecx] 
      dec ecx       ;decrease loop counter 
      cmp eax, 97      ;check if eax is < a 
      jb LoopG3      ; if eax < a try another letter 
      cmp eax, 122     ;else check if eax > z 
      ja LoopG3      ; if eax > z try another letter 
      inc DWORD PTR [arrayCount + eax]   ;incrememnt the letter's count 
      jmp LoopG3 
    pop ebp 
    pop eax 
    pop ecx 
    ret 12  ;return 12 bytes to esp for the 3 parameters (take up 4 bytes each) 
       ; even though they are BYTE 
GetNumLetters ENDP 
+0

爲什麼不使用反彙編程序來查看MASM爲'INVOKE GetNumLetters,OFFSET charInput,OFFSET charCount,stringLength'行做了什麼?大多數調試器應該有內置的反彙編程序,聽起來您已經在使用調試器了。但無論如何,您不需要使用這些僞指令,只需編寫自己的PUSH和CALL指令即可。 (請注意,沒有'PUSH r/m8',所以很可能它會推送垃圾,並且你的函數顯然不會忽略它。還要注意,你可以將'stringLength'定義爲EQU常量,而不是從MEM)。 –

回答

0

你爲什麼不使用反彙編器,看看有什麼MASM做了INVOKE GetNumLetters, OFFSET charInput, OFFSET charCount, stringLength線?大多數調試器應該有內置的反彙編程序,聽起來您已經在使用調試器了。

但無論如何,您不需要使用這些僞指令,只需編寫自己的PUSH和CALL指令即可。

Note that there is no PUSH r/m8,所以它最有可能推動垃圾一起你的字節,你的功能顯然不會忽略它。

另請注意,您可以將stringLength定義爲EQU常量,而不是從mem中加載它。


你可能還打破MASM企圖通過前push ebp/mov ebp, esp做其他推來幫助你。我不知道MASM,但我認爲GetNumLetters PROC, arrayInput: PTR BYTE, arrayCount: PTR BYTE, arrayLength: BYTE會爲您生成一些序言,或者將這些名稱定義爲來自EBP的偏移量,它假定您在函數輸入中首先設置堆棧幀。

再一次,用數字偏移看實際的反彙編,看看究竟發生了什麼。

請注意,通常的調用約定是EAX,ECX和EDX被調用,所以您應該編寫函數來假定他們調用的任何函數都會打開這些regs,並且在您自己的函數中不會浪費保存/恢復它們的說明。即完全刪除push ecxpush eax,而不是在push ebp之後移動它們。

相關問題