Access The Command Line Argument ( MS-DOS, Assembly Language)

 

I tried to understand the stack frame of the asm and thought I can simply access the argument from the command line by offsetting base point by 2.

 

However unlike the subroutine in a C program, it doesn`t work at all!

 

And this is why,

 

http://support.microsoft.com/kb/123729/en-us?fr=1

 

DOS command line argument can be accessed from the PSP (program segment prefix). See the following sample. The offset is 82h starting from "i". And the length of arguments is at 80h (" imhere" contains 7 characters including the space ahead of "i"). Actually it is not an argument at all. Just a tail following the .com. 


C:\Documents and Settings\Administrator\??>debug stack.com imhere
-d 0000 0100
1422:0000  CD 20 FF 9F 00 9A F0 FE-1D F0 4F 03 1C 0E 8A 03   . ........O.....
1422:0010  1C 0E 17 03 1C 0E 0B 0E-01 01 01 00 02 FF FF FF   ................
1422:0020  FF FF FF FF FF FF FF FF-FF FF FF FF C9 13 4C 01   ..............L.
1422:0030  DC 12 14 00 18 00 22 14-FF FF FF FF 00 00 00 00   ......".........
1422:0040  05 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1422:0050  CD 21 CB 00 00 00 00 00-00 00 00 00 00 49 4D 48   .!...........IMH
1422:0060  45 52 45 20 20 20 20 20-00 00 00 00 00 20 20 20   ERE     .....
1422:0070  20 20 20 20 20 20 20 20-00 00 00 00 00 00 00 00           ........
1422:0080  07 20 69 6D 68 65 72 65-0D 6F 6D 20 69 6D 68 65   . imhere.om imhe
1422:0090  72 65 0D 65 0D 64 72 65-73 73 2E 20 20 46 6F 72   re.e.dress.  For
1422:00A0  20 65 78 61 6D 70 6C 65-3A 0D 20 6F 6E 20 4E 54    example:. on NT
1422:00B0  56 44 4D 2C 20 73 70 65-63 69 66 79 20 61 6E 20   VDM, specify an
1422:00C0  69 6E 76 61 6C 69 64 0D-20 6F 6E 6C 79 2E 0D 00   invalid. only...
1422:00D0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1422:00E0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1422:00F0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1422:0100  BD                                                .
-

Does it mean I don`t even bother to use the base pointer?

 

For detailed information, please visit this page.

http://webster.cs.ucr.edu/AoA/DOS/ch13/CH13-8.html

 

How The Stack Work

The following debug process shows what happens when you PUSH or POP.

The characters in red is the location of the stack. Notice that SP starts from FFFE instead from FFFF


C:\Documents and Settings\Administrator\Desktop>debug stack.com
-r
AX=0000  BX=0000  CX=0020  DX=0000  SP=FFFE  BP=0000  SI=0000  DI=0000
DS=1422  ES=1422  SS=1422  CS=1422  IP=0100   NV UP EI PL NZ NA PO NC
1422:0100 55            PUSH    BP
-d fff0 ffff
1422:FFF0  00 00 00 9A 39 39 82 00-06 01 22 14 00 00 00 00   ....99....".....
-t

AX=0000  BX=0000  CX=0020  DX=0000  SP=FFFC  BP=0000  SI=0000  DI=0000
DS=1422  ES=1422  SS=1422  CS=1422  IP=0101   NV UP EI PL NZ NA PO NC
1422:0101 89E5          MOV     BP,SP
-t

AX=0000  BX=0000  CX=0020  DX=0000  SP=FFFC  BP=FFFC  SI=0000  DI=0000
DS=1422  ES=1422  SS=1422  CS=1422  IP=0103   NV UP EI PL NZ NA PO NC
1422:0103 B80500        MOV     AX,0005
-t

AX=0005  BX=0000  CX=0020  DX=0000  SP=FFFC  BP=FFFC  SI=0000  DI=0000
DS=1422  ES=1422  SS=1422  CS=1422  IP=0106   NV UP EI PL NZ NA PO NC
1422:0106 50            PUSH    AX
-d fff0 ffff
1422:FFF0  00 00 05 00 FC FF 06 01-22 14 1C 0E 00 00 00 00   ........".......
-t

AX=0005  BX=0000  CX=0020  DX=0000  SP=FFFA  BP=FFFC  SI=0000  DI=0000
DS=1422  ES=1422  SS=1422  CS=1422  IP=0107   NV UP EI PL NZ NA PO NC
1422:0107 58            POP     AX
-d fff0 ffff
1422:FFF0  05 00 FC FF 07 01 22 14-1C 0E 05 00 00 00 00 00   ......".........
-t

AX=0005  BX=0000  CX=0020  DX=0000  SP=FFFC  BP=FFFC  SI=0000  DI=0000
DS=1422  ES=1422  SS=1422  CS=1422  IP=0108   NV UP EI PL NZ NA PO NC
1422:0108 5D            POP     BP
-d fff0 ffff
1422:FFF0  05 00 05 00 FC FF 08 01-22 14 1C 0E 00 00 00 00   ........".......
-t

AX=0005  BX=0000  CX=0020  DX=0000  SP=FFFE  BP=0000  SI=0000  DI=0000
DS=1422  ES=1422  SS=1422  CS=1422  IP=0109   NV UP EI PL NZ NA PO NC
1422:0109 0000          ADD     [BX+SI],AL                         DS:0000=CD
-d fff0 ffff
1422:FFF0  05 00 05 00 05 00 00 00-09 01 22 14 1C 0E 00 00   ..........".....
-

A Scan Of Two Floppy Disk

Both imgs are formatted into FAT, not quick format.

1. The one at left contains nothing.

2. The one at right contains a file.

The file name is "one.txt".

This text file has only 26 characters which are "abcdefghijklmnopqrstuvwxyz".

How To Access VGA Registers

The following link shows the detailed of accessing VGA registers.

http://www.osdever.net/FreeVGA/vga/vgareg.htm

 

The follwoing has sample codes of accssing the non-extended VGA registers.

http://mcs.uwsuper.edu/~sb/324/Intro/vga.html

 

In case, the above link expired. I put down the main code here.

mov al, 2
mov dx, 3C4h
out dx, al                             ; select map mask register
mov al, 0Fh
mov dx, 3C5h
out dx, al                              ; enable all planes
mov al, es:[di]                      ; must! read from memory
mov es:[di], BYTE PTR 0      ; clear all colors
mov al, Color
out dx, al                              ; set new color
mov es:[di], BYTE PTR 0FFh ; write byte back to memory

 

For example, you want to write to MAP MASK REGISTER,


1. the MAP MASK REGISTER is placed inside the SEQUENCER REGISTERS (3C4h)


2. the MAP MASK REGISTER has the index of 0x02h.

    Means it is in the second one of all the register inside SEQUENCER REGISTER(3C4h)


3. So you tell the SEQUENCER REGISTER(3C4h) the index (0x02h).


3. the write port of the SEQUENCER REGISTER (3C5h) is changed to the MAP MASK REGISTER! You can just write to it, because it is now the MAP MASK REGISTER!

 

 

About Mode 13H (coded in FASM)

org 100h           ; compile it to a .com file

mov ah, 00h     ; set video mode
mov al, 13h      ; set to mode 13h
int 10h        


mov di, 0a000h ; video screen buffer is at segment A000
mov es, di        ; assign the pointer of the segment to ES

mov ax, 43h     ; just a x-coordinate
mov bx, 70h     ; y
mov cx, 140h   ; multiply x by 320
mul cx
add ax, bx        ; add both x and y to get the index
mov di, ax        ; assign the index to be the offset
mov dl, 7         ; assign color value to dl
mov [es:di], dl ; assign it to the the ES:DI

wl:                  ; wait for keyboard input to exit
mov ah,0
int 16h
jz wl

mov ah, 0h      ; restore to text mode
mov al, 3h
int 10h

 

Notes, I made the following mistake, just put it down to remind myself.

 

1. mov ax, 13h   

    can NOT replace  

    mov ah, 0h

    mov al, 13h

 The command is triggered by ah, not al.

 

2. In FASM, to access segment:offset address, use the following syntax.

   e.g.

         mov [es:di], reg

    In TASM, do it in another way.

   e.g.

         mov es:[di], reg

 

3. I noticed that in TASM. You can compile either .EXE file or .COM file by inserting the instruction format MZ into the source file (.asm)

 

4.If the int 16h/ah=0 command is missing, it will return to text mode and the dot will be restored almost at once, so you can hardly recognize the color has been changed in a dot of the screen.

About Mode 13h (draw a line)

org 100h       ; compile it to a .com file

    mov ah, 00h    ; set video mode
    mov al, 13h     ; set to mode 13h
    int 10h        

    mov es, [segV]

    mov ax, [currentX]    ; just a x-coordinate
    mov dx, [pixelsX]   ; multiply x by 320
    mul dx


    mov bx, [currentY]    ; y
    mov cx, [lengthL]      ; the length of the line

drawline:

    sub ax, [pixelsX]
    dec bx

        push ax
    
    add ax, bx      ; add both x and y to get the index
    mov di, ax      ; assign the index to be the offset
    mov dl, [colorC]      ; assign color value to dl
    mov [es:di], dl ; assign it to the the ES:DI
    
    pop ax
    
loop drawline

wl:             ; wait for keyboard input to exit
    mov ah,0
    int 16h
jz wl

    mov ah, 0h    ; restore to text mode
    mov al, 3h
    int 10h

segV dw 0a000h
currentX dw 43h
currentY dw 70h
lengthL dw 30h
pixelsX dw 140h
colorC db 7

Change Color Palette In DOS

org 100h

 ; set video mode
 ;   mov ah, 00h   
 ;   mov al, 13h    
   
;change color palette
mov   dx, 03c8h
xor     al, al
out     dx, al
mov   si, palette        
mov   cx, 300h         ;move number of bytes to cx, equ 3*FF
inc     dx                ;dx = 3c9h
rep     outsb            ;send 768 bytes from pal to port 3c9h

; wait for keyboard input to exit
wl:             
    mov ah,0
    int 16h
    jz wl


; restore to text mode
    mov ah, 0h    
    mov al, 3h
    int 10h

palette:
times 300h-($-$$) db 0f0h

 

1. The program just simply fills the color palette with F0.

One can specified each byte in it.

2. Notice that there is no need to change to Mode 13h or else.

A Simple Program To Test Mouse On Windows (Coded in FASM)

org 100h
xor ax, ax  ; ax=0000h/int=33h This command return the number of
int 33h       ; buttons of your mouse in bx.

mov ah, 09h
mov dx, str1
int 21h

mov ah, 0eh
mov al, bl
add al, 30h
int 10h

mov ah, 09h
mov dx, str2
int 21h

int 20h

str1 db "Your mouse has $"
str2 db " buttons. $"

Macro In FASM

The following article described how to write Macros in FASM.

http://en.wikibooks.org/wiki/X86_Assembly/FASM_Syntax#Macros

 

Macros

Macros in FASM are described in a C-like manner and are created like this:

macro (name) (parameters) {
  macro code.
}

For example, the following could be used to overload the mov instruction to accept three parameters in FASM:

   macro mov op1,op2,op3
    {
     if op3 eq
       mov   op1,op2
     else
       mov   op1,op2
       mov   op2,op3
     end if
    }

if op3 eq means "If the 3rd parameter (op3) equals nothing, or blank" then do a normal mov operation. Else, do the 3 way move operation.

 

Actually, the Macro is totally replaced by the compiler.

This is the original code.

 

org 100h
push ax
macro position x, y {
mov ax, x
mov ax, y
}
position 1h, 2h
pop ax

 

And this is the dump of the .com file with the above code.


-u 0100
1425:0100 50                PUSH    AX
1425:0101 B80100        MOV     AX,0001
1425:0104 B80200        MOV     AX,0002
1425:0107 58                POP     AX

Structure In FASM

Here is the code.

 

org 100h
struc point x,y
{ .x dw x
   .y dw y
}
myP point 12h,13h

 

And here is the binary of the compiled file


-u 0100
1425:0100 1200          ADC     AL,[BX+SI]
1425:0102 1300          ADC     AX,[BX+SI]

What's New

このホームページを使って、

アセンブリ言語の紹介をします。