0

I have defined the array in data segment like - myArray byte 01, 03, 02, 05
In the code I have a line mov eax, BYTE PTR myArray[ecx] the assembler throws a build error here
instruction operands must be of the same size
What could be the reason for this. How do I fix this. I want to loop over this array and print it's
elements

TITLE Subtract Two Nums (SubTwoNums.asm)
; This program collects two numbers and subtracts the second from the first
INCLUDE Irvine32.inc
.data
prompt BYTE "Please enter a number: ", 0
data byte 0A9h
fib  dword 01030205h
msg byte ", " , 0
dwordzeros DWORD 000000h
myArray dword  01,  03,  02,  05

.code

main PROC

mov eax, 0
mov ecx, 0

loop_start:
  cmp ecx, 3
  jge loop_end
  mov eax, myArray[ecx]
  call WriteDec
  mov edx, offset  msg
  call WriteString
  add ecx, 1
  jmp loop_start
loop_end:
exit

main ENDP END main

ishita
  • 23
  • 5

2 Answers2

1

eax is 32 bits, while the value from BYTE PTR myArray[ecx] is 8 bits. Depending on what you're trying to achieve, there are several possible solutions. Among them are

You can move the byte value into a temporary 32 bit register:

movzx ebx,BYTE PTR myArray[ecx]
add eax,ebx

You can accumulate the sum as an 8 bit value:

add al,BYTE PTR myArray[ecx]

You can change the type of myArray from byte to dword.

1201ProgramAlarm
  • 32,384
  • 7
  • 42
  • 56
  • Thanks. It didn't throw the compile error. But when I am looping over the array it does print the first value correctly but the rest values are some random numbers. Before the start of the loop I have `mov eax, 0` inside the loop : `mov eax, myArray[ecx] ` `call WriteDec` `add ecx, 1` It does print the 01 but after that it prints a value like `50331648` – ishita Mar 29 '21 at 20:59
  • @ishita As I've made an (incorrect) assumption about what your problem is, edit your question to include a [mre] so that it is clear what the problem is that you're having. – 1201ProgramAlarm Mar 29 '21 at 21:02
  • I have updated the full code. I think I mistakenly put `add` there whereas I just wanted to print out the numbers in the array – ishita Mar 29 '21 at 21:13
  • @ishita: Your question still says you have a `byte` array, but now the code you posted has `myArray dword 01, 03, 02, 05`. And you only increment ECX by 1, so you're taking a misaligned 4-byte window that was bytes from two different array elements. – Peter Cordes Mar 30 '21 at 01:10
1

It's just the way the opcodes are designed. For most of them there's two forms: operand size "always bytes", and operand size "processor state". The latter depends on execution mode, segment descriptors, and whether the "non-default" size has been specified (prefix bytes toggle individual instructions).

To move smaller data into a larger register, you must use an appropriately sized source (ie BYTE PTR for memory load, as you have done, but cl to move from ecx itself), and either load it similarly into the appropriate smaller destination, or use an instruction that does the conversion explicitely (such as movzx or movsx; move-with-zero-extend/sign-extend, respectively). Unless you are deliberately preserving upper bytes in the destination, prefer the latter.

Also be aware that, any load or alu result into a 32-bit register always clears the upper half of that register's 64-bit form, but the opposite happens for other combinations of sizes.

l.k
  • 199
  • 8