6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sun Oct 06, 2024 9:18 am

All times are UTC




Post new topic Reply to topic  [ 4 posts ] 
Author Message
 Post subject: CMP Instruction
PostPosted: Thu Jun 03, 2004 5:02 pm 
Offline

Joined: Fri May 21, 2004 5:23 pm
Posts: 17
Location: Burlington, ON
Hi,

I've been reading up on the CMP instruction (CMP and SBC are the only two that are giving me any grief) and I found some really good information on this web site, and I was doing well until a question poped into my head.

It says on tutorials/compare_beyond.html that "both [CMP and SBC] affect the N, Z, and C flags in exactly the same way".

Given this information I took the source code for my emulated SBC instruction and poped into my CMP instruction (ignoring the carry, not modifying the registers, and ignoring the BCD handling) and the results are NOT the same. Obviously something is wrong.

However, if I take the table (showing how the flags are set) listed on tutorials/compare_instructions.html and implement that in my CMP instruction and not do any subtracting etc. the instruction works perfect.

Am I missing something?

Any clarification on these two instructions would make me so happy... :?

Thanks,

Andrew :?


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Thu Jun 03, 2004 5:45 pm 
Offline
User avatar

Joined: Tue Mar 02, 2004 8:55 am
Posts: 996
Location: Berkshire, UK
Computers compare numbers by subtracting one value from the other and looking at result. Thats why CMP and SBC set the flags the same way.

For example if you subtract to equal values the result will be zero and would set the 6502's zero flag. If the values are unequal the result would be non zero. If you subtract a big unsigned value from a small one you generate a 'borrow' which clears the carry flag. Subtracting a small unsigned value from a larger (or equal sized) one does not generate a 'borrow' so the carry would be set.

(I won't complicate this discussion with signed values and overflow -- Look them up when you understand unsigned comparison)

There are a couple of key differences between CMP/CPX/CPY and SBC to remember:
    1. CMP/CPX/CPY is not affected by the value of the carry flag at point of execution, SBC is. (CMP/CPX/CPY acts as if there is an implied SEC before the subtraction).
    2. CMP/CPX/CPY does not keep the result of the subtraction, it is used only to set the flags then it is discarded, SBC does.

What the document is saying is that settings of the flags after a code sequence like this...
Code:
        SEC
        LDA VAL1
        SBC VAL2

... will be exactly the same as after ...
Code:
        LDA VAL1
        CMP VAL2

... but the value of accumlator is different (i.e. in the first case A = VAL1-VAL2 and in the second A = VAL1)

_________________
Andrew Jacobs
6502 & PIC Stuff - http://www.obelisk.me.uk/
Cross-Platform 6502/65C02/65816 Macro Assembler - http://www.obelisk.me.uk/dev65/
Open Source Projects - https://github.com/andrew-jacobs


Top
 Profile  
Reply with quote  
 Post subject: Re: CMP Instruction
PostPosted: Fri Jun 04, 2004 5:53 am 
Offline
User avatar

Joined: Thu Mar 11, 2004 7:42 am
Posts: 362
andrewem wrote:
It says on tutorials/compare_beyond.html that "both [CMP and SBC] affect the N, Z, and C flags in exactly the same way".


Not quite. It says that CMP and the sequence SEC SBC affect the N, Z, and C flags in the same way. The D flag is assumed to be zero, so really the SBC sequence is CLD SEC SBC. Anyway, you don't have to take my word for it. Here is a program that demonstrates that it is true. Conveniently, it stops at the first counterexample. It takes about 4 seconds (assuming it passes) at 1 MHz. If it doesn't work on the emulator, then the emulator has a bug.

Code:
; Compare N, Z, and C flag results of CMP and SBC
;
; Returns with ERROR = 0 if the test passes, ERROR = 1 if the test fails
;
; Four additional memory locations are used: ERROR, N1, N2, and SNZC
; These may be located anywhere convenient in RAM
;
TEST  CLD       ; just in case
      LDA #1    ; store 1 in ERROR until the test passes
      STA ERROR
      LDA #0    ; initialize N1 and N2
      STA N1
      STA N2
TEST1 LDA N1

      CMP N2    ; compare N2 to N1

      PHP       ; push CMP flags

      SEC       ; subtract N2 from N1
      SBC N2

      PHP       ; store SEC SBC flags in SNZC
      PLA
      STA SNZC
      PLA       ; pull CMP flags
      EOR SNZC
      AND #$83  ; mask N, z, and C flags
      BNE TEST2
      INC N2
      BNE TEST1
      INC N1
      BNE TEST1
      LDA #0    ; the test passes, so store 0 in ERROR
      STA ERROR
TEST2 RTS


I really didn't intend for the tutorial to be an introduction to the CMP instruction. It's more of a compilation of different comparison techniques and optimization tips. The title is "Beyond 8-bit unsigned comparisons" and one section is named "Review of compare instructions', so a familarity with the CMP instruction was assumed.

andrewem wrote:
Given this information I took the source code for my emulated SBC instruction and poped into my CMP instruction (ignoring the carry, not modifying the registers, and ignoring the BCD handling) and the results are NOT the same. Obviously something is wrong.


I can only guess where the problem might be, but when you "ignore" BCD handling, you must subtract as though the D flag is ZERO, and when you "ignore" the carry you must subtract as though it were ONE.

Also, CMP does not affect the V flag, unlike SBC.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon Jun 07, 2004 8:30 pm 
Offline

Joined: Sun Aug 24, 2003 7:17 pm
Posts: 111
Well, I run the code of "dclxvi" and got as result "ERROR=0" confirming (as expected) that:


"CMP and SBC affect the N, Z, and C flags in exactly the same way"

as expected.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 4 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 10 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: