-1

I'm asked to pass a pointer to an array of byte and make some checks in a PROC and return. I read on Stackoverflow that first I need to dereference the ptr then access it. I'm doing that on line 36 and 37 but this approach is giving me:

A2022 instruction operands must be same size
A2032 invalid use of register

when I try to assembly this code. both arr, pointer and the register is same size (8-bits) and I don't understand why am I getting this error. First error, instruction operands must be same size is for line 36 which is mov bh, arr and the second error invalid use of register is thrown for line 37 which is mov dl, [bh+ecx-1].

Here's the code:

INCLUDE Irvine32.inc

.386
.model flat,stdcall
.stack 4096
ExitProcess proto,dwExitCode:dword

.data
    minArr BYTE 5,2,4,1,3
    maxArr BYTE 9,5,8,4,6
    pinArr BYTE 6,3,4,3,4
    pinArr2 BYTE 5,4,6,2,5
    pinArr3 BYTE 6,2,6,2,5
    pinArr4 BYTE 7,3,7,3,2
    val1 BYTE ?
    val2 BYTE ?
    num  BYTE ?
    str1 BYTE "Valid",0
    str2 BYTE "Invalid",0

.code
Validate_PIN PROC, arr:ptr BYTE
mov eax, 0
mov ebx, 0
mov edx, 0
mov ecx, 5

    L1:
    mov al, [minArr+ecx-1]
    mov bl, [maxArr+ecx-1]
    mov bh, arr
    mov dl, [bh+ecx-1]
    mov num, dl
    
    .IF(num < al) || (num > bl)
    mov edx, OFFSET str2
    mov eax, 0
    mov eax, ecx
    ret
    .ENDIF

    loop L1

    mov edx, OFFSET str1
    mov eax, 0

ret
Validate_PIN ENDP


main PROC
    invoke Validate_PIN, addr pinArr
    call WriteString
    call WriteInt

    invoke Validate_PIN, addr pinArr2
    call WriteString
    call WriteInt

    invoke Validate_PIN, addr pinArr3
    call WriteString
    call WriteInt

    invoke Validate_PIN, addr pinArr4
    call WriteString
    call WriteInt


main ENDP
END main
cptalpdeniz
  • 368
  • 1
  • 11
  • Which lines are 36 and 37, and which lines does MASM complain about? – Peter Cordes Oct 28 '22 at 01:20
  • Sorry for that, it's for the ```mov bh, arr``` and ```mov dl, [bh+ecx-1]``` lines just below L1 – cptalpdeniz Oct 28 '22 at 01:23
  • Edited the question to better reflect where the error is being thrown – cptalpdeniz Oct 28 '22 at 01:26
  • 1
    There is no addressing mode `[bh+ecx-1]`. Also, `arr` is an address you definitely don't want to load it into `bh`. Use `ebx` in both places. – Jester Oct 28 '22 at 01:26
  • I just tried that and it gave me ```byte register cannot be first operand``` error. – cptalpdeniz Oct 28 '22 at 01:28
  • EBX isn't not a byte register (it's a dword, 4 bytes), so an error message complaining about a byte register makes no sense if you tried what Jester suggested. See also [Referencing the contents of a memory location. (x86 addressing modes)](https://stackoverflow.com/q/34058101) and [Using 8-bit registers in x86-64 indexed addressing modes](https://stackoverflow.com/q/39173410) (you can't) – Peter Cordes Oct 28 '22 at 01:40
  • Thank you very much for the quick help. I was able to find what was the reason and fixed it. Thanks again! – cptalpdeniz Oct 28 '22 at 01:51

1 Answers1

0

With the help of @Jester and @Peter Cordes (thank you!), I made the following change in the PROC code block which fixed both issues and the program works without any issue.

L1:
     mov al, [minArr+ecx-1]
     mov esi, arr
     mov dl, [esi+ecx-1]
     mov num, dl
     mov bl, [maxArr+ecx-1]
cptalpdeniz
  • 368
  • 1
  • 11
  • 1
    `mov ebx, 0` / `mov bl, [maxArr+ecx-1]` would be more efficiently written as `movzx ebx, byte ptr [maxArr+ecx-1]`. Also pick a different register for the pointer, like ESI or EDI, so you don't have to keep reloading EBX inside the loop. – Peter Cordes Oct 28 '22 at 01:58
  • Updated the code which utilizes the ESI register and removed reloading EBX. Thanks Peter. – cptalpdeniz Oct 28 '22 at 02:02