使用INVOKE MASM将BYTE参数传递给过程

时间:2016-11-19 19:46:51

标签: assembly parameters invoke masm32 irvine32

所以我试图让用户输入一个字符串,我需要计算用户字符串中出现的字母数。防爆。 “你好”H = 1,e = 1,l = 2,等等。

但是,我在向我的程序GetNumLetters传递一个大小为BYTE的指针和最多132个字符的字符串长度时遇到了麻烦。

当我得到字符串的长度例如“Hello”时stringLength = 5但是当我将stringLength传递给我的过程时,存储该值的参数(arrayLength)不等于5但是就像一些疯狂的数字8398473。当我将stringLength传递给函数GetNumLetters时,我只是不明白为什么arrayLength不等于5。 (我没有测试函数的其余部分,因为我无法得到字符串的大小)。

我的想法是stringLength传递8位,其他24位被随机填充。但是,在这种情况下,我不知道如何将类型转换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

1 个答案:

答案 0 :(得分: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被call-clobbered,所以你应该编写函数来假设他们调用的任何函数都会破坏那些regs,并且在你自己的函数中不浪费指令保存/恢复它们。即完全删除push ecxpush eax,而不是在push ebp之后移动它们。