Так что я пытаюсь ввести пользователя в строку, и мне нужно учитывать количество вхождений букв в строку пользователя. 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
Почему вы не используете дизассемблер, чтобы увидеть, что MASM сделал для 'INVOKE GetNumLetters, OFFSET charInput, OFFSET charCount, строкаLength'? Большинство отладчиков должны иметь встроенный дизассемблер, и похоже, что вы уже используете отладчик. Но в любом случае вам не нужно использовать эти псевдо-инструкции и просто написать свои собственные инструкции PUSH и CALL. (Обратите внимание, что нет 'PUSH r/m8', поэтому, скорее всего, он выталкивает мусор, и ваша функция, по-видимому, не игнорирует его. Также обратите внимание, что вы можете просто определить' stringLength' как постоянную EQU в любом случае, а не загружать его из MEM). –