Would anyone know how to get command-line arguments in NASM16? I am on a Windows XP. I have tried a great deal of things and spent much time searching for an answer to this.

What I ment by command line arguments, something simple like this would be enough.

Filename: Hello1
Params: one two three

So when you type "hello1 one two three", it would see that you typed "one two three", and say something along the lines of

Param 1: One
Param 2: Two
Param 3: Three

I am really against using C libraries (I prefer to do everything purely in assembly).. So if it is possible to do it without C, I would really appreciate your time to answer.

Someone may ask "Why would you want to do this? Just use a higher level language.".. My short answer would be that I enjoy using assembly over a high level language, because of its complexity.

Recommended Answers

All 19 Replies

Not sure what NASM16 is? Is this 16 bit programming?

I would assume so. It came with the book "Assembly language step-by-step". I have had it for a while and it works fine. (After looking around, MASM32 is 32 bit, so I think Nasm16 would be 16 bit).

And not sure if this means it's 16 bit, but I normally put [bits 16] at the top of my code.

Is it possible to get a command-line argument with C? I do not like the use C libraries because to me it does not feel like real assembly. To me, real assembly is 100% machine instructions.

I know how to do it in 64 bit assembly using Linux's as. You just take the offset of the rsp register.i.e

16(%rsp) will get the first command-line argument

In 32 bit Linux's as

8(%esp) to get the first command-line argument

...For 16 bit...I don't think Linux supports 16 bit exe's so I never had the opportunity to try but if it did it would probably be an offset of the ss:sp registers...Hope this helps

Thanks. I would not know how to test this on windows as I have never used Linux, but I appreciate your time to reply.

Thanks. I would not know how to test this on windows as I have never used Linux, but I appreciate your time to reply.

Windows will pass the command line arguments via the stack so you'll get then by taking an offset of the stack pointer. In 16 bit programming I believe that is accomplished with ss:sp

where ss is the segment register and sp is the stack pointer together they will give you the base of the stack

How would I go about doing that? The most i've ever done with assembly was a "Press any key to view its hexidecimal\binary value". I think I may have heard of ss:sp before, but I have no clue how to do anything with them. I understand if you don't have the time to make a code to show me.

That did help a bit. But I still cannot get it to work.. I did, however, make a code as proof that I tried. It is supposed to check if the first argument is the "a" key, then display "It works" if it works.
Here is the code.

[org 0100h]
[section .text]



start:
call arg
cmp bx,61h      ;Check if first arg is "a"
je works	;Say it worked if it did
jne notwork	;Say it didnt work if it didnt


arg: 
        push    bp 
        mov     bp,sp 
        sub     sp,0x40
        mov     bx,[bp+4]
        mov     sp,bp 
        pop     bp 
        ret

works:
mov dx,msg	;Load "works" message into DX
call disp
call exit

notwork:
mov dx,msg1
call disp
call exit

disp:
mov ah,9	;Function 9, display string
int 21h		;Call DOS
ret

exit:
mov  AH,4CH      ; Terminate process DOS service
mov  AL,0        ; Pass this value back to ERRORLEVEL (0)
int  21H         ; Exit




[section .data]
msg db "It worked", 13, 10, "$"
msg1 db "It did'nt work", 13, 10, "$"

I just did, and still could not find anything on passing command-line arguments.

I would try experimenting with this line

mov     bx,[bp+4]

Try values like
mov bx,[bp+8]
mov bx,[bp+12]

Just keep working your way up the stack...

Note the first value on the stack is the number of arguments

Also the command line argument isn't saved on the stack...a pointer to the command line argument is saved on the stack.

So saying "cmp bx,1" would check if there was one argument passed? I tried taking the stack all the way up to 28, and got the same results. "It did'nt work" as my message. I do really appreciate your help by the way, is there a way for me to +rep you?

So saying "cmp bx,1" would check if there was one argument passed? I tried taking the stack all the way up to 28, and got the same results. "It did'nt work" as my message. I do really appreciate your help by the way, is there a way for me to +rep you?

cmp bx, 1 should work...at least its an easy way to see if your checking values on the stack...If you get a true for cmp bx, 1 try changing it to cmp bx, 3 and pass three arguments and see if it still works..If it does then try dereferencing the value ahead of it to see if its your string...Good luck

Still does not work. I'll paste my newer code below. Would compiling it as a .com file have any effect? Because that's what I am using (.com).

[org 0100h]
[section .text]



start:
call arg
cmp bx,1        ;Check for first arg
je works	;Say it worked if it found one
jne notwork	;Say it didnt work if it didnt find one


arg: 
        push    bp 		;Save BP
        mov     bp,sp 		;Move SP into BP
        sub     sp,0x40	
        mov     bx,[bp+4]	;First argument
        mov     sp,bp 		;Move bp into SP
        pop     bp 		;Retore BP
        ret			;Return

works:
mov dx,msg	;Load "works" message into DX
call disp
call exit

notwork:
mov dx,msg1
call disp
call exit

disp:
mov ah,9	;Function 9, display string
int 21h		;Call DOS
ret

exit:
mov  AH,4CH      ; Terminate process DOS service
mov  AL,0        ; Pass this value back to ERRORLEVEL (0)
int  21H         ; Exit




[section .data]
msg db "It worked", 13, 10, "$"
msg1 db "It did'nt work", 13, 10, "$"

16-bit OS dos I need help vortex reign....
Hello, to answer your question NASM16 is a 16-bit (80x86) assembler
for MS-DOS.
To access commandline parameters, they are passed by the
loader (your parent process) into offset 81h in your PSP.
You have your origin set to 100h so I assume you are assembling
a .COM
So try this:

mov cl, [cs:0x80]  ; Get Command Tail Length
mov bx, 0x81        ; place offset of command tail in BX.

Oh yeah, the command tail is but a string of bytes terminated
by a Carriage Return (0xd) and is usually preceded by a
space character (0x20) but not always.
Need more examples, no problem!

Hey, thanks.. but, it did not work.. I may have just set it up wrong though. Would you mind showing a working example of how to use it please?

Code:

[org 0100h]
[section .text]



start:
call arg
call disp
call exit



arg: 
	mov cl, [cs:0x80]  ; Get Command Tail Length
	mov bx, 0x81        ; place offset of command tail in BX.
        ret			;Return


disp:
mov ah,9	;Function 9, display string
int 21h		;Call DOS
ret

exit:
mov  AH,4CH      ; Terminate process DOS service
mov  AL,0        ; Pass this value back to ERRORLEVEL (0)
int  21H         ; Exit




[section .data]

Got it working! Thanks! But to make it work, I have to type a $ on the end of the argument. Ex;

ARGS hello1 hello2 hello3$

Or it will not work, I know it's because I am using 'mov ah,9'.. but is there a different way to print a string?

To print out your commandline arguments with
function 9, simply add a '$' to the end of the actual command tail.
example:

xor bx, bx
mov bl, [0x80]
mov byte [bx+0x81],'$'
mov bx, 0x81

But remember the command tail length does not include the
carriage return, so it will be overwritten.

Yes there is in fact a few other ways to print
a string, here's one using the BIOS:

printstr: ; DS:SI - Null Terminated String
cld
printstr_l:
lodsb
cmp al, 0
jz printstr_e
mov bh, 0
mov ah, 0xe
int 0x10
jmp printstr_l
printstr_e:
ret

Thanks.. This pretty much solved what I was looking for. :)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.