loopsassembly68000easy68k

Easy68K Using a loop, transform text into uppercase


I'm stuck with my code for M68000 using Easy68k simulator. I'm getting some text, I'm storing the text into registry A0, then getting an option to transform it to uppercase and looping through A0.

I'm not sure about the looping part. I'm trying to transform the character into uppercase, but my final output after all the transformations seems to be 0. I'm stuck, can you point me in the right direction?

CR  EQU       $0D
LF  EQU       $0A

START: ORG    $1000
* load dialog WRITE in memory
    LEA WRITE,A1
    MOVE #0,D2 ;D2 stores transformed string

* show prompt WRITE
    MOVE #14,D0
    TRAP #15
* read input WRITE
    MOVE #2,D0 ;lee el input de la cadena
    TRAP #15
    MOVE A1,A0

*Show prompt CHOOSE
SR_CHOOSE:
    LEA CHOOSE,A1     
    MOVE #14,D0
    TRAP #15
    
* Read input CHOOSE
    MOVE #4,D0 ;read num input
    TRAP #15
    CMP.B #1,D1
    BEQ LOOP_UPPER
    BLE SR_CHOOSE

LOOP_UPPER:
    CMP.B   #0, (A0)  ; Compare byte at (A0) with zero (null terminator)
    BEQ     FINISHED
    SUB.B   #32, (A0) ; Convert to uppercase
    MOVE    A0, D2
    TST.B   (A0)+      ; Move to the next character and check for null terminator
    BNE     LOOP_UPPER

*Show transformed text*
FINISHED: 
    MOVE D2,A1  ;Set A1 to D2
    MOVE #14,D0
    TRAP #15

    SIMHALT

*Mensajes
WRITE: DC.W    'ESCRIBE ALGO: ',CR,LF,0
CHOOSE: DC.W    'Transforma a 1-MAYUSCULAS, 2-MINUSCULAS: ',CR,LF,0
        END     START

  1. write text, i.e. hello
  2. choose transform option 1 (UPPERCASE, for now)
  3. loop through text and transform
  4. expected: HELLO, actual: 0

Solution

  • My reading of:

    LOOP_UPPER:
        CMP.B   #0, (A0)  ; Compare byte at (A0) with zero (null terminator)
        BEQ     FINISHED
        SUB.B   #32, (A0) ; Convert to uppercase
        MOVE    A0, D2
        TST.B   (A0)+      ; Move to the next character and check for null terminator
        BNE     LOOP_UPPER
    

    is that D2 will be loaded with the new value of A0 upon every iteration through the loop. So when the loop exits, D2 will point to the trailing null terminator.

    Hence when you print from address D2 after moving it back into A1 after the loop ends, you'll print from the terminator — not from the start of string.

    Probably you just want to take that move out of the loop? So:

        MOVE    A0, D2  ; Keep the string's start address for later
    
    LOOP_UPPER:
        CMP.B   #0, (A0)  ; Compare byte at (A0) with zero (null terminator)
        BEQ     FINISHED
        SUB.B   #32, (A0) ; Convert to uppercase
        TST.B   (A0)+      ; Move to the next character and check for null terminator
        BNE     LOOP_UPPER
    

    And, as an aside, I think all your TST.B/BNE pair achieves is that your loop will terminate either upon hitting a NULL, as per the CMP.B or upon hitting a space, because that's character 32. You probably don't need to conditionals:

    LOOP_UPPER:
        CMP.B   #0, (A0)  ; Compare byte at (A0) with zero (null terminator)
        BEQ     FINISHED  ; Could also be BEQ.S as the destination is close.
        SUB.B   #32, (A0)+ ; Convert to uppercase
        BRA     LOOP_UPPER