Search code examples
assemblytasmemu8086

Can't count string's (array's) length in TASM. Loop ends work


DATA SEGMENT
    STRING DB "ABCDE", 0    
DATA ENDS

SSEG SEGMENT STACK
    DW 100 DUP(?)
SSEG ENDS

CODE SEGMENT
    ASSUME CS:CODE, DS: DATA, SS:SSEG
    
START:
    XOR AX, AX

    MOV SI, OFFSET STRING ; SI ---> FIRST STRING MEMBER IN THIS SPECIFIC PROGRAMM. 
                          ;         USED TO COUNT STRING'S LENGTH
    DEC SI

    ;COUNTING STRING'S LENGTH
    WHILE:INC SI 
          CMP STRING[SI], 0
          JNZ WHILE
    MOV AX, SI ;AX => 5H
        
        
        
    
EXIT:MOV AH, 4CH
     INT 21H
CODE ENDS
END START

Loop ends his work when SI = 2 (STRING[SI] == STRING[2] == "C" == 43H). When SI = 2, ZF = 1. Why it happens?

(I used DEC SI before loop because first instruction into the loop increases SI. Like do-while loop. It used to avoid ZF changing by INC if it was after CMP).


Solution

  • ASSUME CS:CODE, DS: DATA, SS:SSEG
    

    It's not enough to just ASSUME. In the case of the DS segment register, you need to make it happen with the appropriate code. At program start the DS segment register does not automatically point at your DATA SEGMENT.

    mov ax, @DATA
    mov ds, ax
    

    Your loop was scanning the program's PSP and stopped at the third byte because that happened to be zero. {CDh, 20h, 00h, A0h, ... }


    The other error was that you double referenced the string with these instructions:

    MOV SI, OFFSET STRING    1x
    CMP STRING[SI], 0        2x
    

    This error was noticed by Jester

    When you will have corrected both errors, next code will produce SI=5:

    START:
        mov ax, @DATA
        mov ds, ax
        mov si, -1
    WHILE:
        inc si
        cmp STRING[si], 0
        jne WHILE
        ; SI=5