Ok i have a small assembly question

I have this small program that runs with the flat assembler. My problem is that at the receive line function it receives the line and if there isn't a $ typed at the end of the user input the program displays a lot of strange stuff, sometimes beeps and then it seems to terminate without causing any damage to m computer. My question is how do I receive a string of characters with assembly maybe with that function without requiring that the user type $ at the end of his/her input.

ORG 100h ; Start at 100h memory DOS 16 bit .com files
;USE16    ; Use 16 bit mode.
        ; Print line function $ is new line
        ; ah says print line dx is the line to print

        mov ah, 00001001b
        mov dx, msg
        ; Jump to Display It
        jmp DisplayHelloWorld!

DisplayHelloWorld!:
        int 21h

        ; Receive line function
        mov ah, 3fh
        mov dx, Receive
        mov cx, 30
        mov bx, 0
        int 21h

        ; Compare 10d with the value of ah
        cmp dx, Receive
        ; Jump if equal
        je PrintName
        ; Jump if not equal
        jne UnderstandAssembly

UnderstandAssembly:
        ; Call to 21h, again prints line Name
        mov ah, 09h
        mov dx, und
        int 21h

PrintName:
        ; Call to 21h, again prints line Name
        mov ah, 09h
        mov dx, Receive
        int 21h

        ; Tell program to stay alive
        mov ah, 01h
        int 21h
        ; Exit program
        mov ah, 4ch
        int 21h

msg db 'Enter Name: ', '$' ; 0Ah is new line feed, '$' is end of line
und db 'Dx changed before cmp dx, Receive' , '$'
Receive db 30d

The $ sign is the end of string marker and tells the DOS print routine when to stop...that is the reason why you hear bells and whistles or see funky characters on your screen as the DOS print routine is trying its best to make sense of the extended ascii character set which it cant handle...to prevent this from happening change the code so that the user supplied input is concatenated with a $ sign...this way the user doesnt have to type it and clears out all the other issues.

1 Like

alright could you show me how to concatenate '$' to dx before I print Receive. Here's a cleaner version of the program. Line number eighteen is the line that needs concatenating.

ORG 100h ; Start at 100h memory DOS 16 bit .com files
USE16    ; Use 16 bit mode.
        ; Print line function $ is new line
        ; ah says print line dx is the line to print
        mov ah, 00001001b ; 09h
        mov dx, msg
        int 21h

        ; Receive line function
        mov ah, 3fh
        mov dx, Receive
        mov cx, 1Eh       ; 30d
        mov bx, 0h
        int 21h

        ; Call to 21h, again prints line Name
        mov ah, 09h
        mov dx, Receive
        int 21h

        ; Receive one character to STDIN stored in AL
        mov ah, 01h
        int 21h

PrintFiveCharacters:
        ; Write one character to STDOUT
        mov ah, 02h
        mov dl, al
        int 21h
        add cx, 1d
        cmp cx, 4d
        je PrintFiveCharacters

        ; Tell program to stay alive
        mov ah, 01h
        int 21h
        ; Exit program
        mov ah, 4ch
        int 21h

msg db 'Enter Name: ', '$' ; 0Ah is new line feed, '$' is end of line
Receive db 30d

Can you highlight what is line no 18...and is "Receive" a buffer...if so you could give it an initial fill value so you wouldnt have to catenate.

Here's receive it's kind of like the line right before it accept it defines a line that is 30 bytes long and everything else is truncated.

Receive db 30d

Here's line 18 This code sends a string to a file which if 0 I believe sends the string to stdout. I want to concatenate dx and '$', '$' being the string I want to add to the end of dx which should be Receive at this point

        ; Call to 21h, again prints the line
        mov ah, 09h
        mov dx, Receive
        int 21h

And here's a highlight about line 18. dx is the line int 21h will print if you mov ah, 09h and don't change ah. And it actually is a stupid line because receive was already moved into dx right before it. click the image for a list of interrupt options for 21h.

DOS INT 21h - DOS Function Codes
http://spike.scu.edu.au/%7Ebarry/back.gifAH = 09h - WRITE STRING TO STANDARD OUTPUT
  Entry: DS:DX -> '$'-terminated string
  Return: AL = 24h
  Notes: ^C/^Break are checked
  SeeAlso: AH=02h,AH=06h"OUTPUT"

---------- Post updated at 11:21 PM ---------- Previous update was at 11:20 PM ----------

I just want to strcat(dx, '$') right before int 21h/line 19

Are you sure about this...because to me it reads that "Receive" is a label for a single byte that holds the decimal number 30. If you need "Receive" to be a 30 byte buffer then you need to do something like...

Receive db 30 dup('$')

Either catenate a $ sign to the end of Receive or give it an initial fill value...but you cant suffix a $ to the end of dx as it contains the address of the Receive label.

Yes moving "Receive" to dx is somewhat redundant...but it is better to be safe than sorry.

Is there a lower level way to add '$' to the end of receive?

What do you mean by a "lower level way" why cant you define "Receive" to be a 30 byte label and fill it with $ signs...which the code below does.

Receive db 30 dup('$')

how to post a query?

click new thread and post your question

Read the rules, before posting your question

The UNIX and Linux Forums - Forum Rules

I was asking if someone would show me a way without using dup. Is is possible to do that just using the x86 instruction set?

---------- Post updated at 02:13 AM ---------- Previous update was at 02:11 AM ----------

Also if someone enters exactly 30 characters then it beeps.

Ok I fixed the beeping problem but I still haven't learned how to concatenate.
The fix is:

        ; Put this right after line 19
        mov ah, 09h
        mov dx, ENDLINE
        int 21h

ENDLINE db '$' ; was added

I basically send that after I send the variable receive and there are no problems. So solved but I would like to kow how to concatenate with assembly also if you want to post something.

I just thought of a better way to question my concat question.
How can I make dx + 30 = '$'
or maybe how can I make receive[30] = '$'

Well assembly aint C where libc guarantees that every literal will be suffixed with a NULL terminator...if you program in assembly language then learn to do most of the stuff yourself unless there is a lib of assembly routines that you can draw from...and there is no instruction in the x86 set that you can use for this because you need to know the last character of the entered string...and without that knowledge it is impossible.

Again the problem is not when the no of characters entered equals 30 but when someone enters less than 30 characters...and by initialising "Receive" to all $ signs you basically eliminate this issue.

If string length is equal to 30 then you can do this too...

Receive db 30 dup('$'),'$'

Why waste resources just for adding a $ to "Receive+30" when the db directive shown above does it for you.

Unless you know the last character of the entered string it isnt possible to emulate the C function strcat...so forget about it.

Again you are confused between a location dx+30 and its contents [dx+30] so first get that straight...the db directive shown above sets Receive[30]='$' or [dx+30]='$'

Well I solved my problem I was just hoping you would show me how to concatenate. Thanks anyway.

Well i showed you the one and only way it can be done...

Receive db 30 dup('$'),'$'