News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Counting, adding and eax invalid instruction

Started by bcddd214, April 28, 2011, 04:58:31 AM

Previous topic - Next topic

bcddd214

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

donkey

   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.
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

bcddd214

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?

:(

RuiLoureiro

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

qWord

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

FPU in a trice: SmplMath
It's that simple!

bcddd214

 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

RuiLoureiro

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

bcddd214

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

bcddd214

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

RuiLoureiro

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   


RuiLoureiro

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   


baltoro

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.
Baltoro

RuiLoureiro

baltoro,
              yes i never use loop ! I use sub ecx, 1,   jnz  ....

dedndave

LOOP has its' uses   :P
if speed isn't an issue, it can save a couple bytes

baltoro

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,...
Baltoro