• Welcome to Overclockers Forums! Join us to reply in threads, receive reduced ads, and to customize your site experience!

Assembly Help

Overclockers is supported by our readers. When you click a link to make a purchase, we may earn a commission. Learn More.

dicecca112

Member
Joined
Feb 25, 2004
Location
MA, USA
I need some help with an assembly program. Its suppose to decode 4 lines of text 1x44 characters long by subtracting three from the hex representation of the character and then write over it, giving us the final message, but it doesn't do that. It rights the hex characters in sequence starting from 00 and so on.

I've attached the folder as well if anyone wants to try running it

Code:
INCLUDE Irvine32.inc

.data



mycode byte "Li#|rx#fdq#uhdg#wklv#phvvdjh#|rx#kdyh#vroyhg"        ;text to decode
       byte "wkh#sx}}oh#ehfdxvh#rqo|#wkhq#zloo#|rx#vhh#d#"
       byte "phvvdjh#wkdw#pdnjv#dq|#vruw#ri#vhqvh1##Li###"
       byte "|rx#jrw#wklv#idu#frqjudwxodwlrqv$$$$$$$$$$$$"

mycodelen = ($ - mycode)                                        ;determines the length of the code
myrows = mycodelen / LENGTHOF mycode                            ;determines the number of rows
mycols = LENGTHOF mycode                                        ;determines the number of columns
currentcol byte ?                                                ;variable to hold the currentcol
currentrow byte ?                                                ;variable to hold the currentrow    
countsave dword ?                                                ;variable to hold the counter from ecx
delayvar sword ?                                                ;variable to hold the delay number for procedure delay
val3 = 3                                                        ;variable to subtract 3

.code
main proc

                                                                ;set up first loop to write encode text in 4X44 block

mov esi, OFFSET mycode
mov ecx, myrows                                                    ;put the number of rows in ecx
mov currentrow, 0                                                ;set the currentrow number to 0

    OUTERLOOP1:                                                    ;start of outerloop
        mov countsave, ecx                                        ;move the value of ecx to countsave
        mov ecx, mycols                                            ;set ecx to the number of columns
        mov currentcol, 0                                        ;set the currentcol to 0
        
            INNERLOOP1:                                            ;start of innerloop
                mov dh, currentrow                                ;set the x variable of gotoxy to currentrow
                mov dl, currentcol                                ;set the y variable of gotoxy to currentcol
                call Gotoxy                                        ;call gotoxy    
                mov al, [esi]                                    ;mov the address of esi into al
                call writechar                                    ;call writechar
                inc BYTE PTR [esi]                                ;increase the address of ESI by one
                inc currentcol                                    ;increase the curretcol        
            loop INNERLOOP1                                        ;end the loop
            mov ecx, countsave                                    ;move countsave back into ecx to restore later    
            inc currentrow                                        ;increase current row    
            loop OUTERLOOP1                                        ;end the loop

mov delayvar, 1000                                                ;call the delay function
call Delay

                                                                ;set up second loop to write decode text in a 4X44 block

mov esi, OFFSET mycode
mov ecx, myrows                                                    ;put the number of rows in ecx        
mov currentrow, 0                                                ;set the currentrow number to 0

OUTERLOOP2:                                                        ;start of loop
    mov countsave, ecx                                            ;move value of ecx back into countsave
    mov ecx, mycols                                                ;move value of ecx into mycols
    mov currentcol, 0                                            ;set currentcol to 0    
    
        INNERLOOP2:                                                ;start loop
            mov dh, currentrow                                    ;set the x variable of gotoxy to currentrow    
            mov dl, currentcol                                    ;set the y variable of gotoxy to currentcol
            call gotoxy                                            ;call gotoxy
            mov al, [esi]                                        ;mov the address of esi into al
            sub al, val3                                        ;subtract three for al
                        
            call writechar                                        ;call writechar        
            inc BYTE PTR [esi]                                    ;increase the address of esi 
            inc currentcol                                        ;increase the value of currentcol
            mov delayvar, 200                                    ;call delay
            call Delay
            
        loop INNERLOOP2                                            ;end of loop
        
loop OUTERLOOP2                                                    ;end of loop
call Crlf                                                        ;write end of line sequence

exit                                                            ;end of program
main ENDP
 
END main
 
Last edited:
It has been a long time since I did 80x86 assembler, but one of my first thoughts (looking it over quickly) is that I don't see any tests in any of your loops that will stop the loop. For instance, in "INNERLOOP1", you increment "currentcol", but don't compare it to anything to see if you should stop looping.
 
For instance, in "INNERLOOP1", you increment "currentcol", but don't compare it to anything to see if you should stop looping.

Read up on the "loop" command.

As for at least one of the problems: you use ECX in your outer and inner loop without saving its value on the stack and popping it again before you come to
loop INNERLOOP2. When it hits that part of the program, ECX is always 0 and the program never gets to the OUTERLOOP2: label again.
 
well theres been a lot of changes since then. But Kilgens yor suggestion was exactly on the ball. And it now works, perfectly. Thank you.
 
klingens said:
Read up on the "loop" command.

Well, as I said, its been a long time (around 1992) since I did 80x86 assembler. I read "loop", but it didn't register that it was an actual loop command. You jogged my memory and now I do seem to remember the loop command. It used the cx register... I am guessing/remembering it decremented cx and bne to the label. I seem to recall a few other variants like loopne or loopnz.

Spend most of my time working on (non intel 80xxx i.e. MicroChip) microcontrollers now. These MicroChips are rock solid in the noisy (sparks, emf) environments that we use them in, but I often wish they had a few more registers let alone the nice commands like "loop" that do some of the work for you.
 
No one uses loop with x86 anymore: dec cx,jnz labe is faster :)
As for your embedded assembly: anything is better than x86 assembly :p
 
klingens said:
No one uses loop with x86 anymore: dec cx,jnz labe is faster :)
As for your embedded assembly: anything is better than x86 assembly :p

Yea, now that's the type of loop I was expecting to see.

Actually, I have fond memories of x86 assembly, but that (and 6502 assembly on a Commodore Vic20) is what really sparked my interest in computers so may it's more nostalgic than anything.
 
Back