2016-11-19 5 views
1

ユーザを文字列に入力させようとしており、ユーザ文字列に含まれる文字の数をカウントする必要があります。 Ex。 "Hello" H = 1、e = 1、l = 2など。INVOKE MASMを使用したプロシージャへのBYTE引数の受け渡し

しかし、サイズがBYTEのポインタと最大132文字の文字列の長さをGetNumLettersというプロシージャに渡すのに問題があります。

文字列の長さが "Hello"の場合はstringLength = 5ですが、手続きにstringLengthを渡すと、その値を格納するパラメータ(arrayLength)は5に等しくなく、いくつかの狂った番号のようです8398473私はstringLengthを関数GetNumLettersに渡すと、なぜarrayLengthが5でないのか分かりません。 (私は文字列のサイズを取得できないので、残りの関数はテストしていません)。

私の考えは、stringLengthが8ビットを渡しており、24個の他のビットがランダムにパディングされているということです。しかし、私はこの場合、上位24ビット= 0で32ビットになるように型キャストstringLengthをどのように埋めるのか分かりません。あなたはMASMがINVOKE GetNumLetters, OFFSET charInput, OFFSET charCount, stringLengthラインのために何をしたか確認するために逆アセンブラを使用していないのはなぜ

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

?ほとんどのデバッガには逆アセンブラが組み込まれている必要があり、すでにデバッガを使用しているようです。

しかし、とにかく、これらの疑似命令を使用する必要はなく、独自のPUSH命令とCALL命令を書くことができます。

Note that there is no PUSH r/m8だから、おそらくそれはあなたのバイトと一緒にゴミを押して、あなたの機能は明らかにそれを無視していません。

memからロードする代わりに、とにかくstringLengthをEQU定数として定義することもできます。


あなたはおそらくもpush ebp/mov ebp, esp前に他のプッシュを行うことで、あなたを助けるためにMASMの試みを破壊しています。私はMASMを知らないが、私はGetNumLetters PROC, arrayInput: PTR BYTE, arrayCount: PTR BYTE, arrayLength: BYTEがプロローグを生成するか、スタックエントリを最初に設定したと仮定してEBPからのオフセットとしてそれらの名前を定義すると仮定します。

また、数値オフセットを使用して実際の逆アセンブリを調べて、実際に何が起こったかを確認します。

通常の呼び出し規約では、EAX、ECX、およびEDXを呼び出し禁止にするため、呼び出した関数がこれらのregを壊し、自分の関数では無駄にならないと仮定する関数を記述する必要がありますそれらを保存/復元する命令。つまり、push ebpの後に移動する代わりに、push ecxpush eaxを完全に削除します。

関連する問題