2016-11-19 40 views
1

Так что я пытаюсь ввести пользователя в строку, и мне нужно учитывать количество вхождений букв в строку пользователя. Ex. «Hello» H = 1, e = 1, l = 2 и так далее.Передача аргументов BYTE процедуре с использованием INVOKE MASM

Однако у меня возникли проблемы с передачей указателя размера BYTE и длины строки, которая составляет не более 132 символов, моей процедуре, называемой GetNumLetters.

Когда я получаю длину строки, например «Hello», stringLength = 5, но когда я передаю stringLength для моей процедуры, параметр, который сохраняет это значение (arrayLength), не равен 5, но похоже на сумасшедшее число 8398473 Я просто не понимаю, почему arrayLength не равен 5, когда передаю stringLength в функцию GetNumLetters. (Я не тестировал остальную часть функции, так как не могу получить размер строки).

Мое мышление состоит в том, что stringLength передает 8 бит, а 24 других бита случайным образом дополняются. Тем не менее, я не знаю, как бы заполнить тип string stringLength равным 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, строкаLength'? Большинство отладчиков должны иметь встроенный дизассемблер, и похоже, что вы уже используете отладчик. Но в любом случае вам не нужно использовать эти псевдо-инструкции и просто написать свои собственные инструкции 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 должно быть вызвано вызовом, поэтому вы должны написать функции, чтобы предположить, что любые функции, которые они называют, будут сжимать эти регистры, а в ваших собственных функциях не тратьте инструкции по их сохранению/восстановлению. то есть полностью удалите push ecx и push eax, вместо их перемещения после push ebp.