2

My program accepts 4 integers and is suppose to display them back to the user. When printing the values I don't get the expected results. I'm using MASM with Kip's Irvine32 library

My code is:

include irvine32.inc
.data

msg byte "Enter a number",0

arr dword 4 dup(?)
len=($-arr)/4

.code
main PROC

mov edx,offset msg
call writestring
call crlf

mov eax,0
mov ecx,0

.while(ecx<len)
    call readdec
    mov arr[ecx],eax
    inc ecx
.endw

mov ebx,0
mov ecx,0

.while(ecx<len)

    mov ebx,arr[ecx]
    call writedec
    call crlf
    inc ecx
.endw

exit
main ENDP

END main

A sample run of my program:

Enter a number
1
2
3
4
4
4
4
4

After entering the numbers 1,2,3, and 4 the program should have displayed those numbers back to the user. The output I expected is:

Enter a number
1
2
3
4
1
2
3
4

If I modify the loop that prints the numbers so that I place the value to print in EAX instead of EBX with this code:

    mov eax,arr[ecx]
    call writedec

I end up with nonsensical output values like this:

Enter a number
1
2
3
4
67305985
262914
1027
4

Why is my program behaving this way, and how can I modify it to get the expected results?

Michael Petch
  • 46,082
  • 8
  • 107
  • 198
Talal Ahmed
  • 21
  • 1
  • 4

1 Answers1

2

There is only one real issue in the code that appears in different places. When you do something like:

.while(ecx<len)
    call readdec
    mov arr[ecx],eax
    inc ecx
.endw

You must realize that arr[ecx] is the same as arr+ecx. ECX is the offset in bytes added to arr . The issue is that each element of arr is 32-bit (4 bytes) since you declared the array as:

arr dword 4 dup(?)

What you need to do is multiply ECX by the length of each element (in this case 4 bytes). You can do that by multiplying ECX by the size of the elements in the array arr[ecx*4] = arr+(ecx*4) . This form of scaled addressing only supports multiplying by the value of 1,2,4, and 8 in 32-bit code. Your code should have looked like this:

.while(ecx<len)
    call readdec
    mov arr[ecx*4],eax
    inc ecx
.endw

There is a similar issue with the code that calls writedec. As well writedec takes the number to print in EAX, not EBX. This code:

.while(ecx<len)

    mov ebx,arr[ecx]
    call writedec
    call crlf
    inc ecx
.endw

Should be something like:

.while(ecx<len)

    mov eax,arr[ecx*4]
    call writedec
    call crlf
    inc ecx
.endw

One other trick to getting the length of an array in MASM is to use the lengthof pseudo-opcode. Where you wrote:

len=($-arr)/4

You could have used:

len=lengthof arr

lengthof will return the number of elements in arr . MASM takes into account the size of each element size (in this case 4 since you declared arr with DWORD elements). There was nothing wrong with the way you did it, I am offering up another mechanism.

I highly recommend learning to use a debugger to step through your code. A debugger can be an invaluable tool that can allow you to see how things are progressing in the code and see what is in the registers and memory at any given time.

Michael Petch
  • 46,082
  • 8
  • 107
  • 198