• Please review our updated Terms and Rules here

My first ASM Program

per

Veteran Member
Joined
Jan 21, 2008
Messages
3,052
Location
Western Norway
Yah! Today I wrote my first Assembly Program (8086/8088 ASM)! :D It's not a big program, only 300 bytes, but it reads inputs and writes outputs. The program does:

1 Clear the entire screen and hide cursor
2 Waits for a keypress, i'ts using the scan and character code for random number seed.
3 Generates a random double word.
4 Using the random data to output a character on the top line.
5 Scrolls the entire screen one line downwards.
6 Runs through a speed regulating loop routine.
7 Returns to step 3 if no key is pressed.
8 Restore system defaults and return to DOS.

The program is supposed to run on a PC system with MDA and an IBM 5151 monitor. The effect of this program is a "The Matrix" like screensaver.

What is the first thing you have made in Assembly.
 
I think my first practical use of ASM was to provide some additional functions that the Zbasic 3 compiler for the IBM compatibles did not provide. We're talking some very primitive things, like the ability to change into a subdirectory. :)

Zbasic 3 was a great compiler. It had its own dialect of BASIC which was not very compatible with the built-in Microsoft BASIC that most of us have seen. However, it was wicked fast and not saddled down with a lot of the 'cruft' that the Microsoft BASIC had. It was also cross platform - the same dialect was supported by compilers on 3 or 4 different platforms. Each platform had some machine specific extensions, but apparently on the MS DOS version changing directories was not one of them!
 
per,

Great to see people still using x86 asm. It's my favorite language and really the only one that ever made the most sense to me. I've been programming in asm for close to 2 decades now. I learned how by cracking old DOS games, and then ended up getting a job as a BIOS programmer where I wrote in asm for a living.

I've since made the switch to C++, but it was a rocky one-I find C code to be ugly to look at, and reading code horizontally was just weird. ;)

My first asm program was likely hardware detection/information program, which printed out the # of COM ports, LPT ports, floppy drives, amount of memory, etc.

I'm still coding in it today, even at work. Occasionally I'll end up writing a DOS based hardware tester program, and with my pile of routines I've written through the years, I can typically crank out a program in less time than doing it in C.

If nothing else, learning assembly will make you a more logical "break big problems up into smaller ones" thinker, which can apply not only to other programming languages, but also to life itself.

keep it up,

-jeff!
 
Since it's sutch a small program, I'll post the source:

Code:
	MOV	AX,0700H	;Clear screen
	MOV	BX,0200H
	SUB	CX,CX
	MOV	DX,184FH
	INT	10H

	MOV	AX,0100H	;Hide cursor
	SUB	BX,BX
	MOV	CX,2020H
	MOV	DX,BX
	INT	10H

KBCHK:	MOV	AH,01H		;Check keyboard buffer
	INT	16H
	JZ	SETRND		;Skip ahead if empty
	SUB	AH,AH		;Pop one character of the keyboard buffer
	INT	16H
	JMP	KBCHK		;Check for more

SETRND:	SUB	AH,AH		;Waits for a key to be pressed
	INT	16H
	PUSH	AX		;Store the key as seed
	PUSH	AX

MAINLP:	NOP			;Main program starts here

RANDG:	POP	AX		;Get prev random number
	POP	BX		;Get pre-prev random number
	PUSH	AX		;Set prev random number to the new pre-prev random number
	INC	AX		;Add 1 to prev random number
	MOV	CL,07H		;Set shift controller
	ROR	AX,CL		;Rotate 'prev random number'+1 right by 7
	ROL	BX,CL		;Rotate 'pre-prev random number' left by 7
	MUL	BX		;Multiplicate AX by BX
	DEC	AX		;Subtract 1 from AX
	MOV	CL,04H		;Set shift controller
	ROL	AX,CL		;Rotate AX left by 4
	ROR	DX,CL		;Rotate DX right by 4
	MOV	CL,01H		;Set shift controller
	SHR	DH,CL		;Shift DH right by 1 to higher possibility to get it into the right range.
	MOV	CH,AL		;Store random variable 1
	MOV	CL,DH		;Store random variable 2
	MOV	AL,BL		;Combine the rest of the random numbers
	PUSH	AX		;Save the random number on stack
	CMP	CL,4FH		;Check if 'Coloumns' is in range
	JA	RANDG		;Get new random numbers if not
	PUSH	CX		;Save random variables on stack

	MOV	AX,0701H	;Seting up the registers
	MOV	BX,0200H
	SUB	CX,CX
	MOV	DX,184FH
	INT	10H		;Scroll everything down by one row

	MOV	AX,0200H	;Seting up the registers
	SUB	BX,BX
	MOV	CX,BX
	POP	DX		;Get the random number from the stack
	PUSH	DX		;Restore the random number to stack
	MOV	DH,BH
	INT	10H		;Set cursor

	POP	AX		;Get the random number from the stack
	XCHG	AH,AL		;Get the right part of the random number
	MOV	AH,0AH		;Seting up the registers
	SUB	BX,BX
	MOV	CX,0001H
	MOV	DX,BX
	INT	10H		;Write caracter

	MOV	CX,0002H	;Number of speed reducing loops
TMR:	PUSH	CX		;Savd CX from subLoop
	MOV	CX,1000H	;Number of loops per speed reducing loop
TMR1:	NOP			;Time waster
	LOOP	TMR1		;Loop if not done
	POP	CX		;Restore CX from subLoop
	LOOP	TMR		;Loop if not done

	MOV	AH,01H		;Check for a key being pressed
	INT	16H
	JZ	MAINLP		;If no, repeat main program

	POP	AX		;Pop random numbers of the stack
	POP	AX
	SUB	AH,AH		;Throw away the key being pressed
	INT	16H

	MOV	AX,0700H	;Clear screen
	MOV	BX,AX
	SUB	CX,CX
	MOV	DX,184FH
	INT	10H

	MOV	AX,0100H	;Restore default cursor
	SUB	BX,BX
	MOV	CX,0B0CH
	MOV	DX,BX
	INT	10H

	JMP	ENDING		;Skip signature
	DB	' *** GREETINGS! THIS PROGRAM IS PROGRAMMED FOR THE IBM PERSONAL COMPUTER BY What my real name is. 16.FEBRUARY.2008. Enjoy! *** '
ENDING:	RET

This code can be assembled with the A86 assembler avalible at http://eji.com/a86

*Edit*
To make the program compatible with modern computers, edit the statements before TMR: and TMR1:. Default speed settings is ment to be run at 4.77MHh. The program was made to be run with an original IBM 5151 monitor (to get the 'fading' effect).
 
Last edited:
I never dabbled with PC ASM but I did learn a bit about Z-80 assembly language. This was driven by the fact that I had a TRS-80 model 1 clone that wasn't quite compatible, and existing machine code programs had to be disassembled and patches figured out to make the printer work. Had this not been the case, I probably would not have touched assembly code.

Anyway, point is, although it was a steep learning curve, it was very satisfying to code this way. You really feel like you were close to the chips so to speak. I never got past the stage of beginner, but it was fun. It also gave me an appreciation of those who were fluent in the language.
 
Last edited:
First ASM Program...

First ASM Program...

Jeez, that takes me back! I started writing 8086/8 ASM programs back in the mid-80's. I learned by typing in the utility programs that came with every issue of PC Magazine back then. It would usually take me a day or two to type it in, then another day or so to debug it (my bugs, not theirs!). After I got it running correctly (or at least what I assumed was correctly), I would dissect the program instruction by instruction until I understood it completely.

Then I broke down and bought "Assembly Language Primer for the IBM PC & XT" from The Waite Group (which I still have, btw), and read it cover-to-cover. I mainly wrote in x86 ASM for several years, and then started mixing it up with C. When I finally broke down and purchased my first 80486-based PC (I went from 8088-based computers to the 486, skipping over the 286 & 386) in 1992, and started using Windows 3.1x, I more or less abandoned ASM for C.

I still miss those days. ASM was tedious, hard to read and hard to maintain, but it was fun! I have an old Dell laptop which has a Pentium 133 processor, 32 MB of RAM and a 1.2 GB drive. I installed MS-DOS 6.2 + Windows 3.11 on it, and have started playing around with ASM again. It is amazing how much you forget in 16 years! :)
 
We've been working in 8085 assembler lately, one of our ongoing projects. It never ceases to amaze me some of the solutions that were implemented for common tasks, things I never would have thought of if I didn't have some one else's source code to look at first...
 
ASM Frustrations!

ASM Frustrations!

Man, ever since I read this thread, I've been working to get an MS-DOS environment running on my Linux box. First, since I "own" VMWare Workstation, I tried creating a VM for it, and almost had it working right. Almost. :-(

Next, I tried installing the 'dosemu' package, which uses FreeDOS. That worked, but I could not get MASM 6.1 to function correctly under dosemu. Bummer.

Oh well, I guess I'll keep trying. If I try enough variations, I'm bound to get it right (the old: "Even a blind squirrel finds a nut every now and then" syndrome!) :)
 
Great to see more programmers enjoying writing simple but entertaining code. So I started absolutely backwards with learning assembly. In fact, I had read books but not really done anything in it, but using a program "helppc" (we used it as a reference for different BIOS interrupts) and one or two other books a friend and my first endeavor with assembly was writing a proof of concept operating system just to see if we could.

Lots of great ideas and we had bootable code working and began to program around a few oddities like backspace, and enter as well as were able to read fat12 disks to run a program if it was typed. We got up to where we needed to use protected mode memory and realized we have to do the memory map which sucked and was more confusing than we really enjoyed so it put a halt to our project (although we got past that using someone else sample code) but using other written code has always bugged me.

Anyway, still a fun time. Haven't coded much lately except a 16 character password generator (but I did that in qbasic) and that was just to rule out some characters I don't like in OS passwords but was to get past the 15 character rainbow tables generated for NTLM. (Different topic and story).

Keep up the good work though! I think it's pretty fun to see what commands do what and to think of simple little things like that. BTW, the next step (didn't actually go through your code so I apologize if it's already done) is to make it TSR instead of end and wait for a keystroke to activate. You could also add a password feature if you're bold enough.

When I coded the OS I was writing it using dos's debug instead of any real assembler. (Might be a work around for DoctorPepper).

- John
 
When I coded the OS I was writing it using dos's debug instead of any real assembler. (Might be a work around for DoctorPepper).

- John

Now THAT is what I call serious coding! :) (see attached picture below):

I've done the DOS debug thing as well, although it is infinitely more difficult than using a regular text editor to write your code, and a descent assembler/linker chain to build your program.

Basically, I have my old Dell laptop with MS-DOS 6.2 and MASM 6.1. I was just wanting to get an emulated DOS environment on my desktop Linux system, so I wouldn't have to move to another computer to do some hacking in ASM. No biggie, I'm really not that lazy. Really!
 

Attachments

  • real_programmers.jpg
    real_programmers.jpg
    35 KB · Views: 1
I've taken a step futher, and I wrote a version i put into the boot sector of a floppy. Early versions of DOS didn't care about the boot sector to see what format the disks had, so I can still read/write files to the disk.:D

The only differences with the above listed program and the bootable one is that the bootable one types the message "A>" (or "C:\>" in a newer modified version) and waits for a key being pressed before the screen is cleared. The key checking is also removed form the end of the program, so when it is run, it goes into an infinitie loop.

The remaining of the 512 bytes the program takes is filled with an extended comment in ASCII data.

-----

For those who don't know how to write a boot program:

1. Make an ASM program (make sure to only use BIOS calls; DOS calls won't work.)
2. Compile it as a COM file (make sure it is 512 bytes long, if lesser: fill the remaining space at the end of the source with a DB containing text (as many letters as missing bytes) and recompile).
3. When you have the COM file @ 512 bytes, load DOS and type "DEBUG filename.COM"
4. make sure you have a diskette in drive A or B
5. write "W CS:100 0 0 1" if the disk is in A, and "W CS:100 1 0 1" if the disk is in B.
6. write Q

The disk should now be bootable with your ASM program.

----

*Edit* (or additional thoughts)

The 8086/8088 instruction set is pretty simple, in terms of todays intel processors. I just took a look at the newest intel technical manuals, and they uses about 1500 pages (two full books) to explain the instruction set!!! My iAPX 86/88 manual uses only about 10 pages to explain the same thing for the 8086/8088...
 
Last edited:
Update

Update

I've got FreeDOS running in a VMWare session on my Linux box. The default full distribution of FreeDOS comes with five assemblers, I think! The default one to use for 16-bit apps is the Arrowsoft Assembler, version 2. It is supposed to be a superset of MASM, and "should" handle all current MASM source files.

So far I've had good luck with it. I've been feeding it the same ASM files that assemble using MASM 6.1 on my MS-DOS notebook, and they both work fine.

For anyone wanting to "dabble" in DOS, but use a more modern computer, give FreeDOS a try.

http://www.freedos.org
 
Congratulations on your first asm program! One thing I am glad to see is that you have already learned the value of comments in the source. I have been going over some code I wrote a long time ago and am having trouble remembering what I was thinking and/or trying to do :)

Do you have to comment every single line? No, of course not. In fact, sometimes all you need is a single paragraph at the top of the source that explains what that particular module/program is supposed to be doing.
 
Back
Top