The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: bcddd214 on April 28, 2011, 04:58:31 AM

Title: Counting, adding and eax invalid instruction
Post by: bcddd214 on April 28, 2011, 04:58:31 AM
Writing a program that will add incrementally
1+1=2
1+2=3
,,,,
2+1=3
2+2=4

and where I assign eax to a variable it is crapping out.
Line 28 and 31?????

******************************non working code***************************

TITLE count

INCLUDE Irvine32.inc

.data
Count = 10
Count2 = 10

.code


main PROC
LOCAL   incNum:byte
   call ClrScr

; Input the first integer

   mov edx, 0
   mov eax, 0

   Loop1:
   mov edx,[edx+1]
   Call WriteInt
      
   Loop2:
      mov eax, [eax+1]
      call WriteInt
      mov [eax],incNum
      add edx, eax
      call WriteInt
      mov [incNum], eax
      mov ecx, Count
      
   loop Loop2
   ret

; Display the sum

   call WriteInt
   call Crlf
   call Crlf

   mov ecx, Count2
   
loop Loop1
ret
   exit
main ENDP
END main
Title: Re: Counting, adding and eax invalid instruction
Post by: donkey on April 28, 2011, 06:59:26 AM
   mov edx, 0
   mov eax, 0

   Loop1:
   mov edx,[edx+1]


You have loaded the edx and eax registers with a value of 0, then added 1 to them and attempted to load them with the data at the address pointed to by the register (1). You are not allowed to access address 1. If you enclose a register in square brackets you are telling the assembler that it contains an address and when you try to move data to or from it it will be encoded as a "dereferenced" move, in other words it will attempt to get the data at the address, not the value in the register. You can use either LEA, ADD or just plain INC for incrementing the numbers in edx and eax.
Title: Re: Counting, adding and eax invalid instruction
Post by: bcddd214 on April 28, 2011, 11:18:44 AM
I guess where my brain is getting stuck is that if I was counting just one loop I could just use ecx but, I am trying to count a loop withing a counted loop and I am not having any luck with ecx at all either?

:(
Title: Re: Counting, adding and eax invalid instruction
Post by: RuiLoureiro on April 28, 2011, 11:39:39 AM
TITLE count

INCLUDE Irvine32.inc

.data
Count   = 10
Count2  = 10

.code


main PROC
LOCAL   incNum:byte
   call ClrScr

; Input the first integer

   mov edx, 0
   mov eax, 0

   Loop1:
   mov edx,[edx+1]          ; <<<<<<<<<< why this ?
   Call WriteInt
     
   Loop2:
      mov eax, [eax+1]      ;<<<<<<<<<<< why this ?
      call WriteInt
      mov [eax],incNum
      add edx, eax
      call WriteInt
      mov [incNum], eax
      ;mov ecx, Count       ;<<<<<<<<<<<<<<<<<<<<<<< you cannot put this here
     
   loop Loop2
   ;ret                 ;<<<<<<<<<<<<<<<<<<<<<< why this ?

; Display the sum

   call WriteInt
   call Crlf
   call Crlf

   ;mov ecx, Count2     ;<<<<<<<<<<<<<<<<<<<<<<< you cannot put this here
   
loop Loop1
;ret                     ; <<<<<<<<<<<<<<<<<<<< why this ?
   exit
main ENDP
END main
Title: Re: Counting, adding and eax invalid instruction
Post by: qWord on April 28, 2011, 11:52:26 AM
bcddd214 ,

If you want to do simple register arethmetic, you must use LEA instead of MOV:
lea eax,[eax+1]     ; eax = eax + 1
lea eax,[eax+ecx*2] ; eax = eax + ecx*2

Title: Re: Counting, adding and eax invalid instruction
Post by: bcddd214 on April 28, 2011, 12:54:58 PM
 Assembling: nested-loop1.asm
nested-loop1.asm(29) : error A2070: invalid instruction operands
nested-loop1.asm(32) : error A2070: invalid instruction operands
Press any key to continue . . .

*******************code
TITLE count

INCLUDE Irvine32.inc

.data
Count = 10
Count2 = 10

.code


main PROC
LOCAL   incNum:byte
   call ClrScr

; Input the first integer

   mov edx, 0
   mov eax, 0

   Loop1:
   lea edx,[edx+1]
   Call WriteInt
      
   Loop2:
      lea eax,[eax+1]     ; eax = eax + 1
      ;lea eax,[eax+ecx*2] ; eax = eax + ecx*2
      call WriteInt
      mov [eax],incNum
      add edx, eax
      call WriteInt
      mov [incNum], eax
      mov ecx, Count
      
   loop Loop2

; Display the sum

   call WriteInt
   call Crlf
   call Crlf

   mov ecx, Count2
   
loop Loop1

   exit
main ENDP
END main
Title: Re: Counting, adding and eax invalid instruction
Post by: RuiLoureiro on April 28, 2011, 12:57:31 PM
What about this


TITLE count

INCLUDE Irvine32.inc

.data
Count1  dd 10
Count2  dd 10

Counter1    dd 0
Counter2    dd 0

.code


main PROC
;LOCAL   incNum:byte
   call ClrScr

; Input the first integer
   mov  Counter1, 1
   mov  Counter2, 1
   ;
   ; Loop 1
   ; ------
   mov ecx, Count1
Loop1:
push ecx

      mov ecx, Count2       
   Loop2:
      ;
      ; Show Counter1
      ; -------------
      mov  eax, Counter1
      Call WriteInt

      ;
      ; Show Counter2
      ; -------------
      mov eax, Counter2
      call WriteInt
     
      ;
      ; Sum
      ;     
      mov  eax, Counter1
      add  eax, Counter2
      call WriteInt
      call Crlf

      mov eax, Counter2
      add eax, 1
      mov Counter2, eax
     
   loop Loop2

      mov eax, Counter1
      add eax, 1
      mov Counter1, eax

pop ecx   
loop Loop1

   call WaitMsg
   exit
main ENDP
END main

;----------------------------
When we want to use loop
teh best way is to use this:

        mov     ecx, counter
loopX:  push    ecx

        ; do something here

        pop     ecx
        loop    loopX
Title: Re: Counting, adding and eax invalid instruction
Post by: bcddd214 on April 28, 2011, 03:26:15 PM
At first the 'first column' was not counting so I added a push and a pop for eax and that fix the first column.

Can't seem to figure out what to change to get the second column to return to '1' after the first loop?

**********************************code**************************
TITLE count

INCLUDE Irvine32.inc

.data
Count1  dd 10
Count2  dd 10

Counter1    dd 0
Counter2    dd 0

.code


main PROC
;LOCAL   incNum:byte
   call ClrScr

; Input the first integer
   mov  Counter1, 1
   mov  Counter2, 1
   ;
   ; Loop 1
   ; ------
   mov ecx, Count1
Loop1:
push ecx
push eax
      mov ecx, Count2       
   Loop2:
      ; Show Counter1
      mov  eax, Counter1
      Call WriteInt
      ; Show Counter2
      mov eax, Counter2
      call WriteInt
      ; Sum
      mov  eax, Counter1
      add  eax, Counter2
      call WriteInt
      call Crlf
      mov eax, Counter2
      add eax, 1
      mov Counter2, eax
   loop Loop2
      mov eax, Counter1
      add eax, 1
      mov Counter1, eax
pop eax
pop ecx   
loop Loop1

   call WaitMsg
   exit
main ENDP
END main
Title: Re: Counting, adding and eax invalid instruction
Post by: bcddd214 on April 28, 2011, 03:51:51 PM
got it!

**************************code***************************
TITLE count

INCLUDE Irvine32.inc

.data
Count1  dd 10
Count2  dd 10

Counter1    dd 0
Counter2    dd 0

.code


main PROC
;LOCAL   incNum:byte
   call ClrScr

; Input the first integer
   mov  Counter1, 1
   ;
   ; Loop 1
   ; ------
   mov ecx, Count1
Loop1:
push ecx
push eax
      mov ecx, Count2
     mov  Counter2, 1
   Loop2:
      ; Show Counter1
      mov  eax, Counter1
      Call WriteInt
      ; Show Counter2
      mov eax, Counter2
      call WriteInt
      ; Sum
      mov  eax, Counter1
      add  eax, Counter2
      call WriteInt
      call Crlf
      mov eax, Counter2
      add eax, 1
      mov Counter2, eax
   loop Loop2
   mov eax, Counter1
   add eax, 1
   mov Counter1, eax
   pop eax
   pop ecx   
loop Loop1

   call WaitMsg
   exit
main ENDP
END main
Title: Re: Counting, adding and eax invalid instruction
Post by: RuiLoureiro on April 28, 2011, 03:58:19 PM
Sorry, i made a mistake
       yes you got
       

TITLE count

INCLUDE Irvine32.inc

.data
Count1  = 10
Count2  = 10

Counter1    dd 0
Counter2    dd 0

.code


main PROC
;LOCAL   incNum:byte
   call ClrScr

; Input the first integer
   mov  Counter1, 1
   ;mov  Counter2, 1             ; not here
   ;
   ; Loop 1
   ; ------
   mov ecx, Count1
Loop1:
push ecx
;push eax                       ; we dont need to save eax but it was correct
      mov ecx, Count2

      mov  Counter2, 1          ; <<<<<<<<<<<<<<  HERE
     
   Loop2:
      ; Show Counter1
      mov  eax, Counter1
      Call WriteInt
      ; Show Counter2
      mov eax, Counter2
      call WriteInt
      ; Sum
      mov  eax, Counter1
      add  eax, Counter2
      call WriteInt
      call Crlf
      mov eax, Counter2
      add eax, 1
      mov Counter2, eax
   loop Loop2
      mov eax, Counter1
      add eax, 1
      mov Counter1, eax
;pop eax
pop ecx   
loop Loop1

   call WaitMsg
   exit
main ENDP
END main   

Title: Re: Counting, adding and eax invalid instruction
Post by: RuiLoureiro on April 28, 2011, 04:02:09 PM
Another version
       

TITLE count

INCLUDE Irvine32.inc

Count1      equ 10
Count2      equ 10

.data

Counter1    dd 0
Counter2    dd 0

.code


main PROC
;LOCAL   incNum:byte
   call ClrScr

; Input the first integer
   mov  Counter1, 1
   ;
   ; Loop 1
   ; ------
   mov ecx, Count1
Loop1:
push ecx
      mov ecx, Count2

      mov  Counter2, 1          ; <<<<<<<<<<<<<<  HERE
     
   Loop2:
      ; Show Counter1
      mov  eax, Counter1
      Call WriteInt
      ; Show Counter2
      mov eax, Counter2
      call WriteInt
      ; Sum
      mov  eax, Counter1
      add  eax, Counter2
      call WriteInt
      call Crlf

      add   Counter2, 1
   loop Loop2
      add   Counter1, 1
pop ecx   
loop Loop1

   call WaitMsg
   exit
main ENDP
END main   

Title: Re: Counting, adding and eax invalid instruction
Post by: baltoro on April 28, 2011, 04:14:37 PM
While searching the Forum posts, I found this description of using the loop instruction to read ascii characters into a buffer:   
Quote from: MICHAELW..."correct" depends on what your goal is. You could accomplish the same thing with fewer registers. Unless there is some reason to update letter, you could just increment the value in DL. Except for the early processors, LOOP is slower than the equivalent:

dec  ecx
jnz  loop_label

And unlike the equivalent, LOOP can accept only a "short" label, so the jump destination cannot be further back than -128 from the instruction following the LOOP instruction.

Here is a link to the original thread: filling arrays (http://www.masm32.com/board/index.php?topic=7756.0).
Title: Re: Counting, adding and eax invalid instruction
Post by: RuiLoureiro on April 28, 2011, 04:20:37 PM
baltoro,
              yes i never use loop ! I use sub ecx, 1,   jnz  ....
Title: Re: Counting, adding and eax invalid instruction
Post by: dedndave on April 28, 2011, 04:24:13 PM
LOOP has its' uses   :P
if speed isn't an issue, it can save a couple bytes
Title: Re: Counting, adding and eax invalid instruction
Post by: baltoro on April 28, 2011, 04:34:25 PM
The reason I point it out, is that often you want to execute a huge, complex loop (with conditional branches within it),...and, the loop instruction will fail (actually, I think it just fails to compile).
It's pretty easy to implement the equivalent (as MichaelW points out), just by decrementing the counter yourself. The problem there is that if you invoke a routine within your loop that trashes the register you are using as a counter, the whole thing gets whacked (I've done this myself numerous times). But, this is easily avoided, by using simple mechanisms like using PUSH-POP or using MOV to store the data into a memory variable.

...Also, as MichaelW points out:   
Quote from: MICHAELW...Yes, but for conditional jumps when the processor directive is .386 or higher, necessary for 32-bit code, MASM will encode the shortest jump possible, either short or near, but LOOP is only short,...

...But, for the example that bcddd214 is coding above, the loop instruction works just fine,...
Title: Re: Counting, adding and eax invalid instruction
Post by: raymond on April 28, 2011, 08:41:40 PM
QuoteIt's pretty easy to implement the equivalent (as MichaelW points out), just by decrementing the counter yourself.

And, if you're not concerned with timing nor instruction size, it would always be safe (never get trashed by external functions) to use a memory variable as the counter for complex loops.

mov counter,xxx
top_of_loop:
....
....
dec counter
jnz top_of_loop