flat assembler
Message board for the users of flat assembler.

Index > DOS > How to copy command line to a buffer?

Author
Thread Post new topic Reply to topic
hughb



Joined: 28 Jul 2022
Posts: 4
hughb 31 Aug 2024, 23:52
I'm looking to copy the command line string at the end of the program segment prefix (PSP) to a buffer I've allocated for my program. However, since I'm still learning I don't know quite how to go about that because I'm using "format MZ" and dividing my program into different segments. The PSP is on a different memory segment than my buffer, so how do I copy the string from one place to another? Do I keep DS as it is and set ES to point to the "data" segment and copy the string that way?

Here is a simplified example of my program:

Code:
format MZ
entry main:start
stack 0x100

label CMD_STRING 0x81

segment main
start:
    ; program here, want to copy command line into 'buf' described below
segment data
buf rb 64
    
Post 31 Aug 2024, 23:52
View user's profile Send private message Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 4043
Location: vpcmpistri
bitRAKE 01 Sep 2024, 00:30
Code:
; Command line echo program - MZ executable

format MZ
entry codeseg:Start

CMD_STRING equ 0x80 ; length followed by string

segment codeseg use16
Start:
    mov ah, 62h             ; Get PSP segment
    int 21h
    mov ds, bx              ; DS = PSP segment

    xor ax, ax

    ; Source string at PSP:CMD_STRING
    mov si, CMD_STRING      ; Offset 80h is where the command line length is stored in PSP
    lodsb
    xchg cx, ax             ; CX = length of command line
    jcxz no_command         ; If no command line, skip

    ; Destination buffer in ES:DI
    push dataseg
    pop es
    mov di, buffer

    rep movsb

    ; Terminate the string in the buffer
    mov al, '$'
    stosb

    ; Print the string at DS:DX
    push dataseg
    pop ds
    lea dx, [buffer]
    mov ah, 09h             ; DOS print string function
    int 21h

no_command:
    ; Terminate the program
    mov ah, 4Ch
    int 21h

segment dataseg use16
buffer rb 64    

_________________
¯\(°_o)/¯ “languages are not safe - uses can be” Bjarne Stroustrup
Post 01 Sep 2024, 00:30
View user's profile Send private message Visit poster's website Reply with quote
uu



Joined: 20 Jul 2024
Posts: 44
uu 01 Sep 2024, 08:54
bitRAKE's code example is more advanced and shorter.

I do have another example when I did my hexdump for DOS program.

Code:
format MZ
entry main:start
stack 100h

label CMD_LENGTH byte at 80h
label CMD_STRING byte at 81h

segment main

start:
        mov     ax,text
        mov     ds,ax

        xor     cx, cx
        mov     cl, [es:CMD_LENGTH]
        lea     di, [es:CMD_STRING]
        lea     si, [_filename]
        cmp     cx, 0
        jz      quit
again:
        mov     al, [es:di]
        cmp     al, ' '
        jnz     continue
        inc     di
        jmp     again
continue:
        cmp     al, 13
        jz      skip
        mov     [si], al
        inc     si
        inc     di
        loop    again
skip:
        xor     al, al
        mov     [si],al
        inc     si
        mov     al, '$'
        mov     [si], al

        mov     dx, _filename
        mov     ah, 9
        int     21h

quit:
        mov     ax, 4c00h
        int     21h

segment text

_filename rb 255    


Description: Comparison between "bitRAKE" and my example code
Filesize: 12.93 KB
Viewed: 1026 Time(s)

Capture.PNG


Post 01 Sep 2024, 08:54
View user's profile Send private message Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 959
Location: Russia
macomics 01 Sep 2024, 10:39
I've fixed one small logical error for you.
Code:
format MZ
entry main:start
stack 100h

label CMD_LENGTH byte at 80h
label CMD_STRING byte at 81h

segment main

start:
        mov     ax,text
        mov     ds,ax

        xor     cx, cx
        mov     cl, [es:CMD_LENGTH]
        lea     di, [es:CMD_STRING]
        lea     si, [_filename]
        cmp     cx, 0
        jz      quit
again:
        mov     al, [es:di]
        cmp     al, ' '
        jnz     continue
        inc     di
        loop    again ; jmp     again
        jmp     quit
continue:
        cmp     al, 13
        jz      skip
        mov     [si], al
        inc     si
        inc     di
        loop    continue ; loop    again
skip:
        xor     al, al
        mov     [si],al
        inc     si
        mov     al, '$'
        mov     [si], al

        mov     dx, _filename
        mov     ah, 9
        int     21h

quit:
        mov     ax, 4c00h
        int     21h

segment text

_filename rb 255    
You do not need to skip spaces inside the argument string. You also do not сonsider length counter in the loop again.


Last edited by macomics on 01 Sep 2024, 10:46; edited 1 time in total
Post 01 Sep 2024, 10:39
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20344
Location: In your JS exploiting you and your system
revolution 01 Sep 2024, 10:46
I get the feeling this is homework help.
Post 01 Sep 2024, 10:46
View user's profile Send private message Visit poster's website Reply with quote
uu



Joined: 20 Jul 2024
Posts: 44
uu 01 Sep 2024, 11:10
macomics wrote:
I've fixed one small logical error for you.....You do not need to skip spaces inside the argument string. You also do not сonsider length counter in the loop again.


Thanks for your kind effort, but I ran into incorrect output when testing.

(But I am not in my best analytic mind to debug as I haven't touched Assembly for weeks)


Description:
Filesize: 15.15 KB
Viewed: 990 Time(s)

Capture.PNG


Post 01 Sep 2024, 11:10
View user's profile Send private message Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 959
Location: Russia
macomics 01 Sep 2024, 11:14
Code:
format MZ
entry main:start
stack 100h

label CMD_LINE_OFFSET byte at 80h
label CMD_LENGTH byte at bx+0
label CMD_STRING byte at bx+1

segment main

start:
        mov     ax,text
        mov     es,ax

        xor     cx, cx
        mov     bx, CMD_LINE_OFFSET
        mov     cl, [CMD_LENGTH]
        lea     si, [CMD_STRING]
        lea     di, [_filename]
        cmp     cx, 0
        jz      quit
again:
        cmp     byte [si], ' '
        jnz     continue
        inc     si
        loop    again ; jmp     again
        jmp     quit
continue:
        mov     al, [si]
        cmp     al, 13
        jz      skip
        mov     [es:di], al
        inc     si
        inc     di
        loop    continue ; loop    again
skip:
        mov     byte [es:di], '$'
        push    es
        pop     ds

        mov     dx, _filename
        mov     ah, 9
        int     21h

quit:
        mov     ax, 4c00h
        int     21h

segment text

_filename rb 255    


Last edited by macomics on 01 Sep 2024, 11:20; edited 1 time in total
Post 01 Sep 2024, 11:14
View user's profile Send private message Reply with quote
uu



Joined: 20 Jul 2024
Posts: 44
uu 01 Sep 2024, 11:17
Thank you, macomics, for your refined version that doesn't skip spaces.

Very Happy


Description:
Filesize: 15.09 KB
Viewed: 978 Time(s)

Capture.PNG


Post 01 Sep 2024, 11:17
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1631
Location: Toronto, Canada
AsmGuru62 01 Sep 2024, 11:31
Most likely a homework, but we still help if some code was written, but not working.
And MZ?! Really?
I wrote so much for DOS using FASM and never crossed the 64Kb limit for DOS COM file.
And in case of COM file the copy of text is this loop:
Code:
; point SI to a source buffer
; point DI to a destination buffer
@@:
lodsb
stosb
test al,al
jnz @r
    

In 2003 I coded the Data Center (parts, clients, inventory, etc.) for a small car dealership.
All UI screens and all data searching and indexing --- all fit into COM file.
MZ files are for something really big, definitely not for a school project.
Post 01 Sep 2024, 11:31
View user's profile Send private message Send e-mail Reply with quote
hughb



Joined: 28 Jul 2022
Posts: 4
hughb 01 Sep 2024, 15:39
Thanks for the help everyone!
Upon reflection, my question does sound like homework, but I wish I was that young!
I'm older and learning DOS assembly for fun. It's fixed in time so I don't have to worry about new versions, frameworks, etc.

My program is small enough to fit into a COM file, but I'm exploring and learning more.
Post 01 Sep 2024, 15:39
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.