flat assembler
Message board for the users of flat assembler.

Index > DOS > INT 2FH AX=4810H - Read Command Line

Goto page Previous  1, 2
Author
Thread Post new topic Reply to topic
geekbasic@gmx.com



Joined: 25 Oct 2022
Posts: 71
Location: Arizona
geekbasic@gmx.com 26 Jan 2023, 23:42
So, it would seem that my book means line of input from the keyboard when it says read command line.

That's very confusing! Especially due to the fact that it was in the "Other" section in the index.
Post 26 Jan 2023, 23:42
View user's profile Send private message Visit poster's website Reply with quote
geekbasic@gmx.com



Joined: 25 Oct 2022
Posts: 71
Location: Arizona
geekbasic@gmx.com 27 Jan 2023, 00:35
I see that my book has things worded in confusingly.

I am trying to implement macomics example to work with my compiler.

Am I going to make my computer explode for trying to write it this way?

Code:

use16
org 256

cld
lea di,[parameters]
lea si,[129]
movzx cx,[128]
rep movs byte [di],[si]
mov al,'$'
stos byte [di]

mov dx,parameters
mov ah,9
int 33

int 32

parameters db "",0
rb 1023

    
Post 27 Jan 2023, 00:35
View user's profile Send private message Visit poster's website Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 909
Location: Russia
macomics 27 Jan 2023, 00:45
I declared these values as labels for a reason. So they acquired size. Otherwise, you will have to specify the size every time you apply.
Code:
use16
org 256

cld
lea di,[parameters]
lea si,[129]
movzx cx,byte [128] ; <- You must specify the size
rep movs byte [di],[si]
mov al,'$'
stos byte [di]

mov dx,parameters
mov ah,9
int 33

int 32

parameters db "",0
rb 1023    
It is better to use these declarations
Code:
label cmd_line_size byte at 128
label cmd_line_text byte at 129    


ADD:
Code:
use16
org 256
mov ax, cs
mov ds, ax
mov es, ax

mov dx, args
mov ax, 0x4810
int 47

mov ah, 9
int 33

mov ax, 76 * 256 + 0
int 33

args db 128, 127 dup ( ' ' ), 13, 10, '$'    


Last edited by macomics on 27 Jan 2023, 01:01; edited 1 time in total
Post 27 Jan 2023, 00:45
View user's profile Send private message Reply with quote
geekbasic@gmx.com



Joined: 25 Oct 2022
Posts: 71
Location: Arizona
geekbasic@gmx.com 27 Jan 2023, 00:54
Does it matter where these declarations appear in the code?

Is it totally necessary to use LEA or is there a way to write this with just MOV?
Post 27 Jan 2023, 00:54
View user's profile Send private message Visit poster's website Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 909
Location: Russia
macomics 27 Jan 2023, 01:05
Considering that these are labels - no.

You can use either mov or lea.
Post 27 Jan 2023, 01:05
View user's profile Send private message Reply with quote
geekbasic@gmx.com



Joined: 25 Oct 2022
Posts: 71
Location: Arizona
geekbasic@gmx.com 27 Jan 2023, 03:12
I think I have just one more question for now.

What's the simplest way to add a 0 byte to the end of the string?
I want it to work with my 0 terminated print function.
Would it be much to remove the $ and add a zero?

I'd rather not use my clunky cut and concat routines if possible.
Post 27 Jan 2023, 03:12
View user's profile Send private message Visit poster's website Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 909
Location: Russia
macomics 27 Jan 2023, 05:31
Code:
cld
lea di,[parameters]
lea si,[129]
movzx cx,byte [128] ; <- You must specify the size
rep movs byte [di],[si]
mov al,'$' ; <- Here $ is added at the end of the string for the function ah=9/int 33. You can simply change $ to 0 in al.
stos byte [di]    


Code:
replace_dollar_2_zero:
    mov al, '$'
    or cx, -1
    lea dx, [string]
    repne scas byte [di]
    jnz @f
    sub [es:di - 1], al
@@:
    retn    
Post 27 Jan 2023, 05:31
View user's profile Send private message Reply with quote
FlierMate11



Joined: 13 Oct 2022
Posts: 94
FlierMate11 27 Jan 2023, 07:44
It is "lea di, [string]" in replace_dollar_2_zero I supposed?

Thanks macomics for the code. I might need to trim leading space in the command-line, so I added this:
Code:
        mov     cx, [_len]
        lea     si, [_cmd]
        lea     di, [_filename]
again:
        lodsb
        cmp     al, ' '
        jz      again
        stosb
        loop    again 
    

...where cx is the length of command-line.

I am doing my hexdump for DOS, trying to opening file with filename passed in commnad-line.
Post 27 Jan 2023, 07:44
View user's profile Send private message Visit poster's website Reply with quote
sinsi



Joined: 10 Aug 2007
Posts: 789
Location: Adelaide
sinsi 27 Jan 2023, 08:27
On entry to a MZ the ES register (and DS) points to the PSP segment, at ES:80h is the command line.
Just a reminder that LODS uses DS:SI by default and STOS uses ES:DI
Post 27 Jan 2023, 08:27
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8340
Location: Kraków, Poland
Tomasz Grysztar 27 Jan 2023, 08:28
geekbasic@gmx.com wrote:
There seems to be conflicting documentation regarding int 2fh ax=4810h

My source is "The Programmers PC Sourcebook" by Thom Hogan from Microsoft Press dated 1991.

What is my book referring to if not the Command Line?
I highly recommend Ralf Brown's Interrupt List as an advanced reference. Back in the 90's I learned to use it as THE reference, in cases of doubt it was usually the INTLIST that had the most reliable and complete information.

Note that INT 2Fh is an interrupt for "multiplexing" interfacing various resident programs ("TSRs"), extending DOS with sets of function specific to a given program. See the general note:
Code:
INT 2F - Multiplex - NOTES
        AH = identifier of program which is to handle the interrupt
           00h-3Fh reserved for IBM (for DOS)
           40h-7Fh reserved for Microsoft (for DOS)
           80h-B7h reserved for IBM
           B8h-BFh reserved for networks
           C0h-FFh reserved for applications
        AL is the function code
   This is a general mechanism for verifying the presence of a TSR and
   communicating with it.  When searching for a free identifier code for AH
   using the installation check (AL=00h), the calling program should set
   BX/CX/DX to 0000h and must not depend on any registers other than CS:IP
   and SS:SP to be valid on return, since numerous programs now use additional
   registers on input and/or output for the installation check.    
Keep that in mind every time you see any function of interrupt 2Fh.

Checking function AX=4810h (when viewing the file under DOS I would do it by typing "-2f4810" into a search box, for this reason I always used a single combined INTERRUP.LST file) leads to the following information:
Code:
INT 2F - DOS 5+ DOSKEY, PCED v2.1 - READ INPUT LINE FROM CONSOLE
        AX = 4810h
        DS:DX -> line buffer (see #01344 at INT 21/AH=0Ah)
Return: AX = 0000h if successful
Notes:  the first byte (length) of the buffer MUST be 80h, or MS-DOS's DOSKEY
          chains to the previous handler; PCED and Novell DOS allow sizes
          other than 80h
        if the user's input is a macro name, no text is placed in the buffer
          even though AX=0000h on return; the program must immediately issue
          this call again to retrieve the expansion of the macro.  Similarly,
          if the user enters a special parameter such as $*, this call must
          be repeated to retrieve the expansion; on the second call, DOSKEY
          overwrites the macro name on the screen with its expansion.
        unlike DOSKEY, PCED expands all macros on the first call, so it is
          not necessary to make two calls; since the buffer is not empty on
          return, DOSKEY-aware programs will not make the second call
        DOSKEY chains if AL is not 00h or 10h on entry
        this function is supported by Novell DOS 7 DOSKEY
SeeAlso: AX=4800h,INT 21/AH=0Ah    
We learn from this that this is a function of DOSKEY (so it's only present under DOS when you have DOSKEY loaded), although it is also provided by PCED. It is also clearly said to be reading user input from the console, which is not the same thing as the command line that was entered to execute the program, although I see how one could have the things confused.

For the command line itself, and PSP in general, Interrupt List also provides lots of valuable information. Search the file for "(PSP)" text and you should find the following table:
Code:
Format of Program Segment Prefix (PSP):
Offset  Size    Description     (Table 01378)
 00h  2 BYTEs   INT 20 instruction for CP/M CALL 0 program termination
                the CDh 20h here is often used as a signature for a valid PSP
 02h    WORD    segment of first byte beyond memory allocated to program
 04h    BYTE    (DOS) unused filler
                (OS/2) count of fake DOS version returns
 05h    BYTE    CP/M CALL 5 service request (FAR CALL to absolute 000C0h)
                BUG: (DOS 2+ DEBUG) PSPs created by DEBUG point at 000BEh
 06h    WORD    CP/M compatibility--size of first segment for .COM files
 08h  2 BYTEs   remainder of FAR JMP at 05h
 0Ah    DWORD   stored INT 22 termination address
 0Eh    DWORD   stored INT 23 control-Break handler address
 12h    DWORD   DOS 1.1+ stored INT 24 critical error handler address
 16h    WORD    segment of parent PSP    
I'm cutting it, as there's so much information in there, but I'm going to extract some bits about the command line:
Code:
 80h 128 BYTEs  commandline / default DTA
                command tail is BYTE for length of tail, N BYTEs for the tail,
                  followed by a BYTE containing 0Dh
Notes:
        for 4DOS and Windows95, the command tail may be more than 126
          characters; in that case, the length byte will be set to 7Fh (with
          an 0Dh in the  127th position at offset FFh), and the first 126
          characters will be stored in the PSP, with the entire command line
          in the environment variable CMDLINE; under at least some versions
          of 4DOS, the byte at offset FFh is *not* set to 0Dh, so there is no
          terminating carriage return in the PSP's command tail.
BUG:    When shelling out from the Borland Pascal 7.00 IDE, overly-long
          command lines will not be delimited by a 0Dh character, and the
          length byte is set to 80h!  A workaround is to always patch in a
          0Dh at the last position of the command line buffer before scanning
          the command line.    
I cannot praise enough how invaluable this resource was back in the 90's, when internet access was scarce - it was a highly treasured set of files for ones like me, that would likely get it shared by friend on a couple of 1.44 floppies.
Post 27 Jan 2023, 08:28
View user's profile Send private message Visit poster's website Reply with quote
geekbasic@gmx.com



Joined: 25 Oct 2022
Posts: 71
Location: Arizona
geekbasic@gmx.com 29 Jan 2023, 21:33
Thank you for providing this information and clearing that up. Otherwise this thread may appear confusing to people.

I think it's time I switch over to Ralf Brown's list. Everyone seems to recommend it the most.
Post 29 Jan 2023, 21:33
View user's profile Send private message Visit poster's website Reply with quote
sinsi



Joined: 10 Aug 2007
Posts: 789
Location: Adelaide
sinsi 30 Jan 2023, 00:58
There is a HTML version here http://www.ctyme.com/intr/int.htm
Post 30 Jan 2023, 00:58
View user's profile Send private message Reply with quote
bitdog2u



Joined: 31 Jan 2023
Posts: 3
Location: Ketchikan, Alaska
bitdog2u 16 Aug 2023, 14:20
[/code]
ORG 100h
USE16
MOV SI,80h ;ARGC
LODSB
ADD SI,AX
MOV byte [SI],'$' ;or zero=0 for your print2 0 proc.
MOV DX,82h ;ARGV
MOV AH,9 ;print string to $ function
INT 21h
RET ;end program

;or this,

$=256
use16
mov si,80h ;ARGC
lodsw ;SI = ARGV now
mov cl,al ; off by one ?
mov di,buffer
repz movsb ;copy it somewhere
ret ; end program
buffer: ; pre reserved bytes = 63k+
Post 16 Aug 2023, 14:20
View user's profile Send private message Reply with quote
bitdog2u



Joined: 31 Jan 2023
Posts: 3
Location: Ketchikan, Alaska
bitdog2u 16 Aug 2023, 15:16
;Use code to change your code.

macro ENDm xx1 { MOV byte [ENDING+1],xx1 }
ORG 100h
USE16

MOV SI,80h
LODSW ; SI=82h now
OR AL,AL
JZ BYE ; no input....

PUSH word 0xB800 ; Vmode3 SEG adr
POP ES ;Vmode# at [0:0449h]
MOV DI,160*5 ;Line5 Page0
MOV AH,12 ;color red

ENDm 13 ; change the code
CALL Print0 ;= Print to CR=13 now
ENDm 0 ; change it back
BYE: RET ;EXIT program

zzTOPs: STOSW
Print0: LODSB ; proc
ENDING: CMP AL,0
JNZ zzTOPs
RET
Post 16 Aug 2023, 15:16
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page Previous  1, 2

< 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.