I have a (seemingly) simple question to read in a string and print it out again using x86 interrupt based assembly. The problem i’m having is accessing the string that has been read in properly. The variable – input db 20, 0, " " is my initial string. After I call the input interrupt, the 0 should now hold the length of the string, which I need to store and pass to cx when I call the print interrupt. 20 is the max length of input. I end up with two problems – how do I access the length of the string (I’ve using an arbitrary number, which either chops it short or prints garbage after the end) and how do I access the string without the number bit at the start? Any help appreciated, my attempt is:
(I use tasm & Tlink under win 7 32 bit, and also under dos box emulation)
;7. Read in a String of characters and Print the string back out.
.model small
.stack 100h
.data
colour db 00001111b
input db 20, 0, " "
strlen dw 20; this should be ?
.code
main:
call initsegs
call readstring
call printstring
call exit
PROC printstring
push ax bx cx dx bp
mov ah, 13h ; int 13h of 10h, print a string
mov al, 1 ; write mode: colour on bl
mov bh, 0 ; video page zero
mov bl, colour; colour attribute
mov cx, strlen; getting this is the problem
mov dh, 10; row
mov dl, 10; column
mov bp, offset input ; es:bp needs to point at string..this points to string but includes its max and length at the start
int 10h;
pop bp dx cx bx ax
ret
ENDP printstring
PROC readstring
push ax dx
mov ah, 0ah ; function a of 21h - read a string
mov dx, offset input ; reads string into DS:DX so DX needs be offset of string variable
int 21h ; call the interrupt
;mov strlen ....something
pop dx ax
ret
ENDP readstring
PROC exit
mov ah, 4ch
INT 21h
RET
ENDP Exit
PROC initsegs
push ax
mov ax, @DATA
mov ds, ax
mov es, ax
pop ax
RET
ENDP initsegs
end main
What you have here is known as
Pascal String. The original version (used in 16bit Pascal language) used first byte to hold the length of the string, and the rest of bytes contaned the actual string (not zero terminated). This gives maximum length of 255 bytes.The version uses 32bit Delphi used slighly different approach:
It’s similar to your case, but you use BYTE for size instead of DWORD.
The standard way to work with them is to keep the pointer to the actual character string, and to use negative offsets for special fields, like in: