String comparison procedure in Z80 assembler

ZXNet echo conference «code.zx»

From Ivan Roshin To All 5 July 2003

Hello, All! ═══════════════════ cmp_str .t ══════════════════ (c) Ivan Roshchin, Moscow Fido: 2:5020/689.53 ZXNet: 500:95/462.53 E-mail: bestview@mtu-net.ru WWW: http://www.ivr.da.ru String comparison procedure in Z80 assembler ═════════════════════ ══════════════════════ ("Radiomir. Your computer" 6/2003) When writing the BestView program, I needed a procedure comparing two strings with the following input and output parameters: in HL the address of the first line is specified, in DE - the address the second line, in BC - the length of the line (not equal to 0); output flag Z is set if the lines match, and cleared otherwise. The string comparison algorithm is very simple: we take bytes by address specified in DE, compare it with the byte at the address specified in HL, in case of inequality, we exit the procedure (flag Z is cleared), in case of equality, increase HL and DE by 1 (so they will now point to the following bytes of the compared strings) and decrease BC by 1 (i.e. decrease counter); if after decreasing BC<>0, proceed to comparison next bytes, otherwise (BC=0) the lines match, then we exit procedures (the Z flag is set). Accordingly, I wrote a procedure that used in BestView up to version 2.14 inclusive: COMP_ST LD A,(DE) CP(HL) RET NZ ;Do not match.INC HL ;! INCDE ;! DEC BC ;! LD A,B ;! OR C ;! JR NZ,COMP_ST RET ;Coincid. And recently, while looking through it, I noticed this: that: increase HL and DE by 1, decrease BC by 1, check BC by equality to zero - but in the instruction system of the Z80 processor there is the team that does it all! The LDI instruction copies a byte from (HL) to (DE), increments HL and DE by 1, decrease BC by 1, reset P/V flag if after decreases BC=0, and sets the P/V flag otherwise. That is, this command does almost the same as the marked one "!" fragment of the procedure, only, firstly, also copies a byte from (HL) into (DE), and secondly puts information about the equality of BC zero to the P/V flag, not to the Z flag. Copying a byte from (HL) to (DE) in the procedure in question completely useless. However, if you look more closely, you can notice that after the RET NZ command, a byte is at the address specified in HL, obviously equal to the byte at the address specified in DE (indeed, if they were not equal, then after comparing them the procedure would exit). And if the bytes are equal, then copying from (HL) to (DE) is not will change (DE), that is, it will be a harmless side effect. Then the entire section of the procedure marked "!" can be replacedby one LDI command, simultaneously replacing the conditional command go to the beginning of the cycle (JR NZ,COMP_ST) to the command JP PE,COMP_ST - after all, now it is the P/V flag that indicates fulfillment or failure of the condition BC=0. But one more problem remains: when exiting the procedure in If the strings match, the Z flag must be set. And if in the original version of the procedure it was automatically set when checking the loop exit condition (BC=0), then Now the check for this condition is not associated with the Z flag at all. First I wanted to add before exiting the procedure in case line matches (i.e. before the last RET command) command XOR A, which sets the Z flag. But, after looking in the reference book, I saw that the LDI command does not change the Z flag, but looking at procedure, I saw that after comparing the next bytes of the strings the Z flag will definitely be set (after all, the lines match!). So Thus, nothing special needed to be added. So, an optimized version of the procedure: COMP_ST LD A,(DE) CP(HL) RET NZ ;Do not match. LDI ;Ha Z has no effect! JP PE,COMP_ST RET ;Coincident, Z=1! The length of the procedure decreased by 2 bytes, and the execution time reduced as follows: in the case when compared the strings do not match (and their first n bytes match),the gain is 12n cycles, and in the case when the lines coincide (n is their length), the gain is 12(n-1)+7 cycles. ════════════════════════ ════════════════════════ Best regards, Ivan Roshchin.

From Kirill Frolov To All 14 July 2003

Press RESET immediately, Ivan Roshin! IR> ("Radiomir. Your computer" 6/2003) IR> When writing the BestView program, I needed a procedure IR> comparing two strings with the following input and output It would be better if someone wrote a quick procedure for parsing regular expressions having the function of fuzzy comparison of strings (with texts in Russian otherwise it’s difficult), in Z80 assembler. I haven’t seen it anywhere, but it’s a useful thing for searching for something in the text, for parsing, etc...