Here we are again. For my first tutorial, see Assembly #1 Reverse a string. Bill set me up for a second challenge, and I took it up. This is another great bite sized exercise to learn how to compare blocks of memory. In this exercise we will compare 2 strings and let the user know if they are equal. We will make use of BASIC again to:
The purpose of this project is to write another simple assembly language program, and learn to use a few more assembly mnemonics. Specifically the ones for comparing values. You will want to make sure you use the $JR
compiler directive to make jumps easier.
The mnemonics for comparing are:
MNEMONIC OPERATION FLAGS EFFECTED
CPIM n [P] - n C,Z
CPIA n A - n C,Z
CPMA [P] - A C,Z
Use the following truth table to figure out what flags will be set.
TRUTH TABLE
EXAMPLE FLAGS MEANING
4 - 5 C=1,Z=0 left < right
5 - 5 C=0,Z=1 left = right
6 - 5 C=0,Z=0 left > right
You’re likely to find CPMA
is the real workhorse when dealing with data. CPIA
and CPIM
are used when dealing with known values; Like if you want to see if something equals 0.
Once you have compared, you will use a branch mnemonic to jump to a new piece of code.
MNEMONIC OPERATION
JPNZ nm jump to nm if Z=0
JPNC nm jump to nm if C=0
JPZ nm jump to nm if Z=1
JPC nm jump to nm if C=1
JP nm jump to nm regardless of flags
As an example, lets say you want to see if the A reg
equals the number 5. You would use the following code:
CMIA 5 # A - n, check if A reg is 5
JPZ PLACE1
# continue as A is not 5
RTN
PLACE1: # A is 5
RTN
JPZ
jumps to PLACE1
if the zero flag was set, which according to the truth table means A equals 5.
This will be our memory setup. Program start is 49217.
ADDRESS ASM VAR COMMENT
49200 RESULT Result (1 equal | 0 not equal)
49201 - 49207 SRC1 String 1
49208 SRCLEN1 Length of string 1
49209 - 49215 SRC2 String 2
49216 SRCLEN2 Length of string 2
49217 Program start
Our assembly program will compare the 2 strings SRC1
and SRC2
, making note of the string lengths SRCLEN1
& SRCLEN2
, and store the result in address RESULT
(49200).
Compile and load at address 49200 (&C030). bin2wav.exe --type=bin --pc=1360 --addr=0xC030 output.bin
and CLOAD M
on your pocket computer.
##############################################################################
# Compare the strings SRC1 and SRC2 to see if they
# are equal. Store 0 in RESULT if no, 1 if they are.
##############################################################################
$JR
org &C030
I_REG EQU 0 # Internal Registers
J_REG EQU 1
A_REG EQU 2
B_REG EQU 3
XL_REG EQU 4
XH_REG EQU 5
YL_REG EQU 6
YH_REG EQU 7
K_REG EQU 8
L_REG EQU 9
M_REG EQU 10
N_REG EQU 11
PORTC EQU 95
# define data and put some dummy data in place
RESULT: DB 0
SRC1: DB 48 49 50 51 52 53 54
SRCLEN1: DB 1
SRC2: DB 65 66 67 68 69 70 71
SRCLEN2: DB 1
START:
# Point the X register to SRC1
LP XH_REG # P <- XH
LIA HB@SRC1
EXAM # A <-> [P]
LP XL_REG # P <- XL
LIA LB@SRC1
EXAM # A <-> [P] => X now contains SRC1
DX # prep for ++X inside check1
# Point the Y register to SRC2
LP YH_REG # P <- YH
LIA HB@SRC2
EXAM # A <-> [P]
LP YL_REG # P <- YL
LIA LB@SRC2
EXAM # A <-> [P] => Y now contains SRC2
DY # prep for ++Y inside check1
# put srclen1 into A and srclen2 into B
LIDP SRCLEN2
LDD # [DP] -> A - srclen -> A
EXAB # A <-> B - B contains srclen2
LIDP SRCLEN1
LDD # A contains srclen1
# check if strings are the same length
LP B_REG # P points to B reg
CPMA # [P] - A -> C,Z # compare A and B
JPNZ NOT_EQUAL
# check byte by byte to see if the strings are the same length
lp K_REG
exam # K now contains srclen1
check1:
# put src1 bytes into A, src2 bytes into B, then compare A & B
# load B from Y
iy # ++Y -> DP
ldd # [Y] -> A
exab # B contains [Y]
# load A from X
ixl # ++X -> DP, [DP] -> A
lp B_REG
cpma # compare A and B
jpnz not_equal
# decrement K reg
deck
jpnz check1 # keep checking
# fall through into equal
equal:
lidp result
lia 1
std
rtn
not_equal:
lidp result
ra # 0 -> A
std
rtn
You can type RUN
to start this program once loaded.
100 "S" WAIT 0
110 A=49201:R=49200
120 INPUT "String 1:";X$
130 INPUT "String 2:";Y$
135 PRINT "POKING"
140 K = LEN X$
150 L = LEN Y$
200 FOR I=1 TO K
205 V = ASC(MID$(X$,I,1))
210 POKE A,V
220 A=A+1
230 NEXT I
240 A=49209
250 FOR I=1 TO L
265 V = ASC(MID$(Y$,I,1))
270 POKE A,V
280 A=A+1
290 NEXT I
295 POKE 49208,K : POKE 49216,L
300 PRINT "CALLING ML"
310 CALL 49217
320 IF PEEK 49200 = 0 PRINT "NOT EQUAL"
330 IF PEEK 49200 = 1 PRINT "EQUAL"
Feel free to drop me a line at eightbit at axorion dot com. You can also start a thread on Simons Pocket Computer Forum. Best to let me know you did though, in case I don’t see your forum entry right away.
Copyright © 2025, Lee Patterson