Click to See Complete Forum and Search --> : logical error


brad sue
February 21st, 2009, 12:43 AM
Hi I have this program that counts the values of a table. All values are initial at 1.
I use the assembler masm 6.11

The problem I have is that the program does not go through the loop 10 times after the first iteration, it exits. I don see what is wrong can someone see the problem?


;
; register usage: BX= pointer to table.
; CX= counter
; AX= current partial sum
;
;
;
TITLE ADDTABLE
.MODEL SMALL ;conventions- small model
;
; stack initialization
;
.stack 100H ; Allocate 256 bytes stack
;
;
; Local data
;
.DATA
COUNTER DW 10 ;length of table
TABLE DW 100 DUP(1) ;Reserve storage for table
RESULT DW ? ;sum of entries
;
; Code Segment
;
;
.CODE
START:
MOV AX, @DATA ;Load segment register
MOV DS, AX ;Into DS register
;
; Initialization area
;
MOV BX, OFFSET TABLE ; initialize PTR to top of table
MOV CX, COUNTER ; initialize counter to # of entries
XOR AX,AX ; clear current sum
;
; Loop to add table entries
;
ADDLOP:
ADD AX,WORD PTR [BX] ; ADD NEXT ENTRY
INC BX ;Point to next entry by incrementing
INC BX
LOOPNZ ADDLOP ;If not, add next entry
;
; DONE, store sum and Exit
;
MOV RESULT, AX ;store SUM
MOV AX, 4C00H ;InA and call DOS
;
END START
Thank you

Slicerwizard
February 24th, 2009, 01:12 AM
The problem is that you're using LOOPNZ.

rxbagain
March 1st, 2009, 02:56 AM
I don't see any problem in your code. The LOOPNZ should be ok.

How are you debuging ung program? Are you using debug.exe? Maybe you are using "p" (proceed) instead of "t" (trace) that is why you cant see the loop in action.

If you don't care about the value of zero flag and loop only until CX == 0, simply use LOOP.

I'm not sure though.

Slicerwizard
March 1st, 2009, 04:32 AM
Why do you think LOOPNZ is OK? (it's not)

rxbagain
March 1st, 2009, 04:47 AM
Why do you think LOOPNZ is OK? (it's not)LOOPNZ means loop "WHILE CX <> 0 AND ZERO FLAG IS CLEAR". Within the loop (up to 10), the ZERO FLAG IS ALWAYS CLEAR so the NZ is always true. In effect it's just like a simple LOOP

I'll ask you the same question. What makes you think it's wrong? :D If it's not LOOPNZ or LOOP then what should it be?

ckweius
March 1st, 2009, 06:44 AM
LOOPNZ will continue the loop as long as CX is not zero OR the zero condition is not set.

So for your case, just use LOOP, which will drop to next instruction when CX equals 0.

rxbagain
March 1st, 2009, 10:20 AM
LOOPNZ will continue the loop as long as CX is not zero OR the zero condition is not set.

So for your case, just use LOOP, which will drop to next instruction when CX equals 0.

Just to make it clear "LOOPNZ will continue the loop as long as CX is not zero AND the zero condition is not set" not "LOOPNZ will continue the loop as long as CX is not zero OR the zero condition is not set"

If you say OR, it will continue the loop even if CX has already rolled over as long as "the zero condition is not set".

All these LOOP, LOOPNZ and LOOPZ will stop whenever CX becomes 0. The only difference is that LOOPNZ and LOOPZ can terminate earlier depending on the ZERO FLAG. LOOPNZ will terminate earlier when "Zero flag is set". while the LOOPZ will terminate earlier when "Zero flag is clear".

But ckweius is right, you dont need to check the value of Zero flag so you can just use a simple LOOP (although LOOPNZ should be no problem in your case)

Edit: I attached the snapshot how I tested the code using debug and verified that LOOPNZ is working.

ckweius
March 1st, 2009, 08:42 PM
Just to make it clear "LOOPNZ will continue the loop as long as CX is not zero AND the zero condition is not set" not "LOOPNZ will continue the loop as long as CX is not zero OR the zero condition is not set"

If you say OR, it will continue the loop even if CX has already rolled over as long as "the zero condition is not set".


No, I am pretty sure that LOOPNZ will continue the loop as long as CX is not zero OR the zero condition is not set. Read this (http://www.osdata.com/topic/language/asm/progcont.htm)

rxbagain
March 1st, 2009, 09:11 PM
Read carefully the link you gave. It says there "continues to the next instruction (to exit the loop)" NOT "continue the loop". When we say "continue the loop", It should mean "to continue to iterate" not to end the iteration.


LOOPNZ Loop While Not Zero; Intel 80x86; used to implement DO loops, WHILE loops, UNTIL loops, and similar constructs, decrements the ECX or CX (count) register and then tests to see if it is zero, if the ECX or CX register is zero or the Zero Flag is set (one) then the program continues to the next instruction (to exit the loop), otherwise the program makes a byte branch (to continue the loop); equivalent to LOOPNE; does not modify flags


You must be trying to say the "otherwise" part so you should also change the "OR" to "AND" in your statement
LOOPNZ will continue the loop as long as CX is not zero AND the Zero Flag is not set.

Try to debug the code and see how the LOOPNZ works.

rxbagain
March 1st, 2009, 10:40 PM
Here's another debug screen I made. I used "p" (proceed) in this case. Take a look of the values of AX, BX and CX. Although you can't see the loop going back to "ADD AX, [BX]", you can tell by the values of the registers that 10 iterations was performed properly. Maybe this is how brad debugs his code and he is wondering why the loop did not jump to "ADD AX, [BX]".

Unless brad has some other code within the loop (if he omitted some code) that could affect the zero flag when LOOPNZ is encountered, his code should work fine.

ckweius
March 2nd, 2009, 05:12 AM
I have done the code trace, rxbagain is correct.