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
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.
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 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
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
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
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
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
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
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
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
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).
baltoro,
yes i never use loop ! I use sub ecx, 1, jnz ....
LOOP has its' uses :P
if speed isn't an issue, it can save a couple bytes
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,...
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