otacon14112
Experienced Member
Now that I got my 20x4 LCD display working on my 8088 homebrew computer, I'm playing around with strings. I'm trying to learn proper string manipulation, and so I thought I'd start with trying to find the length of a string. It sounds simple, especially since there is scasb. But I'm doing something wrong. Here's my code so far:
The display shows:
and flickers. I have a 373 latching any data being sent out ports, and the eight LEDs flash as the LCD flickers. When I run my simple "Hello" program that only prints "Hello", it works just fine, and the last thing the 373 latches when it runs the simple "Hello" program is the LCD command (02h) to make it latch the command to print the last character, which is what it should do. But when I run this program, I have determined that when I call GetStrLen is when it acts funny.
I have tried to follow the advice of various articles showing how to use scasb. Maybe I'm not utilizing the stack correctly. The reason I pushed the string onto the stack, is because when I write more advanced programs, strings from input will not be hardcoded using "db", and so I was trying to experiment and practice how I would manipulate those strings.
I intended this program to:
If anyone could help me I'd greatly appreciate. Thanks in advance! :D
Code:
; ************************************************
; * *
; * Experimenting with strings and their length *
; * *
; ************************************************
;
;
;
section .data
_1KB equ 1024
_2KB equ 2048
_32KB equ 32*_1KB
_128KB equ 128*_1KB
_256KB equ 256*_1KB
PORT1 equ 0x01
PORT2 equ 0x02
ROM_SIZE equ _128KB ; Set size of ROM here
org 0x100
section .text
start:
; Set stuff up
mov sp,0xFFFF ; Initialize the stack pointer to 64KB.
; This is 384KB in memory, 64KB
; above the SS
mov bx, ss ; Initialize BX to 0, since SS hasn't
; changed yet
mov ax,0x5000 ; Initialize SS to be at 320KB,
mov ss,ax ; 64KB below the end of RAM
call InitPorts ; Set up the 8255
call InitDelay ; Give the LCD time to self-initialize
call InitLCD ; Run the initialization sequence
mov al,"H"
call PrintChar
mov al,"e"
call PrintChar
mov al,"l"
call PrintChar
mov al,"l"
call PrintChar
mov al,"o"
call PrintChar
mov al, ":"
call PrintChar
; Now try to use the stack to store a string
push 0x00 ; Null char to terminate string
push "g"
push "n"
push "i"
push "r"
push "t"
push "s"
mov ax, sp ; Put address of string into AX
call GetStrLen
mov al, cl ; Put str len into AL
add al, 48 ; Convert the number to ASCII
call PrintChar
jmp $
GetStrLen:
mov di, ax ; Move string address into di
mov cx, 0xFFFF ; Initialize CX
sub al, al ; Initialize AL
cld
repne scasb
not ecx
sub ecx, 1 ; Get the length of the string
ret
InitDelay: mov word [bx],0x01FF; Set the countdown timer.
StartInitDel: dec word [bx] ; Decrement it by 1 each time.
cmp word [bx],00h ; If the timer has counted down
; all the way, return to the
; 'nextloop' label so that it
; can move on to the next hex
; value to display on the LEDs.
jnz StartInitDel ; If the counter hasn't counted
; down to 00h yet, keep going.
ret
CharDelay: mov word [bx],0x001F; Set the countdown timer.
StartCharDel: dec word [bx] ; Decrement it by 1 each time.
cmp word [bx],00h ; If the timer has counted down
; all the way, return to the
; 'nextloop' label so that it
; can move on to the next hex
; value to display on the LEDs.
jnz StartCharDel ; If the counter hasn't counted
; down to 00h yet, keep going.
ret
LatchDelay: mov word [bx],0x002F; Set the countdown timer.
StartDel: dec word [bx] ; Decrement it by 1 each time.
cmp word [bx],00h ; If the timer has counted down
; all the way, return to the
; 'nextloop' label so that it
; can move on to the next hex
; value to display on the LEDs.
jnz StartDel ; If the counter hasn't counted
; down to 00h yet, keep going.
ret
PrintChar:
push ax ; Save the ASCII character
mov al,0x02 ; Make RS high, E low
out PORT2,al
pop ax ; Get the ASCII character back
out PORT1,al ; Send the character to the display
mov al,0x06 ; Make E and RS high
out PORT2,al
call CharDelay
mov al,0x02 ; Make RS high, E low
out PORT2,al
call CharDelay
ret
LatchCMD:
mov al,0x04 ; Make E high to latch the data
out PORT2,al
call LatchDelay
call ClearPort2
call LatchDelay
ret
ClearPort2:
mov al,0x00 ; Clear the port
out PORT2,al
ret
InitPorts:
mov al,0x90 ; This sets the 8255 to operate
out 0x03,al ; in Mode 0 (basic I/O)
; Input Output
; ***** ******
; Port 0 Ports 1, 2
ret
InitLCD:
; Reset sequence 1
mov al,0x30
out PORT1,al
call LatchCMD
; Reset sequence 2
mov al,0x30
out PORT1,al
call LatchCMD
; Reset sequence 3
mov al,0x30
out PORT1,al
call LatchCMD
; 8-bit, 2 lines, 5x8 characters
mov al,0x38
out PORT1,al
call LatchCMD
; End of step 1
; Increment, and no display shift
mov al,0x06
out PORT1,al
call LatchCMD
; Turn display on, cursor on, and do not blink the
; character at cursor
mov al,0x0C
out PORT1,al
call LatchCMD
; Clear the display
mov al,0x01
out PORT1,al
call LatchCMD
; DDRAM address set to home, position top left most character
mov al,0x80
out PORT1,al
call LatchCMD
ret
times ((ROM_SIZE-16) - ($-$$)) db 0
db 0xEA ; far jump
dw start ; Sets the offset IP value
dw 0x10000-(ROM_SIZE/16)-0x10; Target CS value
times ROM_SIZE - ($-$$) db 0
The display shows:
Code:
Hello:
I have tried to follow the advice of various articles showing how to use scasb. Maybe I'm not utilizing the stack correctly. The reason I pushed the string onto the stack, is because when I write more advanced programs, strings from input will not be hardcoded using "db", and so I was trying to experiment and practice how I would manipulate those strings.
I intended this program to:
- Display "Hello:"
- Load a string into memory with a trailing NULL character to symbolize the end of the string
- Put the address of the string into what I've read are the necessary registers for scasb to do its job
- Invert the value of CX
- Decrement it by 1 to get the length of the string (which I read was a clever and quick way to find it)
- This may be another part where I'm getting confused. I think the integer value of the length of the string would be in the lower byte, so I'm converting the lower byte to ASCII
- Print the length
If anyone could help me I'd greatly appreciate. Thanks in advance! :D