View Full Version : My first ASM Program
per
February 16th, 2008, 08:58 AM
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.
mbbrutman
February 16th, 2008, 09:26 AM
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!
hargle
February 16th, 2008, 10:34 AM
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!
per
February 16th, 2008, 10:57 AM
Since it's sutch a small program, I'll post the source:
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).
tezza
February 16th, 2008, 12:27 PM
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.
DoctorPepper
February 16th, 2008, 02:55 PM
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! :-)
SwedaGuy
February 16th, 2008, 05:08 PM
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...
DoctorPepper
February 17th, 2008, 12:20 PM
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!) :-)
barythrin
February 17th, 2008, 07:36 PM
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
DoctorPepper
February 18th, 2008, 03:03 AM
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!
per
February 18th, 2008, 03:41 AM
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...
DoctorPepper
March 27th, 2008, 03:46 AM
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
Trixter
March 27th, 2008, 11:35 AM
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.
vBulletin® v3.8.4, Copyright ©2000-2009, Jelsoft Enterprises Ltd.