A86 assembly programming part 1
----------------------------------------------------
~contents~
----------------
* Introduction
* Segments and offsets
* Registers and interrupts
* Our first program
* what comes next
* where to find more information
[introduction]
First things first if you don't already have a copy of a86 I suggest you download it now. You can find it here: http://eji.com/a86.zip -
also here's the FAQ: http://webster.cs.ucr.edu/Articles/X86FAQ/A86.html I
If you have any issues send me an email.
[Segments and offsets]
Now comes one of the most important yet confusing subjects in the field of assembly programming. The guys that designed the 8086 chip designed it so that it couldn't access above one megabyte because they thought that no one would ever need to use more than that!
Let me show you the problem. Say you want to access a whole megabyte which would mean 20 bits are needed. (one bit being either a one or a zero) Registers only have 16 bits and the guys that made chip didn't want to use two because that would be 32 bits and again they thought back then that was just to much for anyone. It get past this we do the addressing with two registers but not 32 bits.
Instead of increasing the size of the 8086 CPU register where stuck with only 16-bits but
the way we use those registers changed. Whenever a program needs to use an absolute memory location
the instruction set groups two 16-bit registers.
To find the absolute memory location use this formula.
Absolute memory location = (segment value * 16) + offset value
essentially what we are doing us multiplying by 16 (or shifting one hexadecimal byte to the left and adding an
extra 0 to the end) then finally adding the value of the offset value.
Lets try a couple:
F0000 <---- This last zero is the extra of which I spoke
+ FFFD
------
FFFFD or 1,048,573
You see the SEGMENT:OFFSET pair F000:FFFD was computed fairly easy by inserting the zero at the end of the segment
value (which is the same as multiplying by 16) and the adding the offset value. To help you with the conversion's
I'd suggest you make a hex <-> dec conversion program. If your just starting out with programming these site should
help you: http://www.cplusplus.com, http://www.bloodshed.net/devcpp.html, http://www.programmersheaven.com/
Getting back to the task at hand I'd like to mention some of the downsides of in using this type of instruction
set. when your dealing with large numbers there are a numerous pairs that refer to THE SAME EXACT MEMORY LOCATION.
0007:7B90 0008:7B80 0009:7B70 000A:7B60
0047:7790 0048:7780 0049:7770 004A:7760
0077:7490 0078:7480 0079:7470 007A:7460
01FF:5C10 0200:5C00 0201:5BF0 0202:5BE0
07BB:0050 07BC:0040 07BD:0030 07BE:0020
All of the SEGMENT:OFFSET pairs above refer to exactly the same location. Now here is how to find that location:
Divide the absolute address by 16 (which shifts the hex digits one place to the right), the throw away any
fractional remainder and add 1. Basically as a rule lets add 1 byte to the segment number of the offset os 000Fh
15 or less. Lets try one!
SEGMENT:OFFSET
0000:7C00
OFFSET / 16 + 1 = number of different pairs that can be used
7C00h / 10h =
31744 / 16 = 1984 + 1 = 1985 [7C1h]
Try a couple on your own until you feel comfortable.
[Registers and Interrupts]
First off I need to tell you the difference between hardware and software interrupts.
Hardware interrupts are triggered by hardware and software respectively. You should not that when you press a
key on your keyboard the PIC (Programmable Interrupt Controller chip prioritizes the interrupts and interfaces
with the 8086 CPU. Here a list of standard IRQ's. I'd suggest you find out personally what your IRQ's are. This
could come in handy with future programming explorations FYI.
{Input on 8259 80x86 INT Device}
IRQ 0 8 Timer chip
IRQ 1 9 Keyboard
IRQ 2 0Ah Cascade for controller 2 (IRQ 8-15)
IRQ 3 0Bh Serial port 2
IRQ 4 0Ch Serial port 1
IRQ 5 0Dh Parallel port 2 in AT, reserved in PS/2 systems
IRQ 6 0Eh Diskette drive
IRQ 7 0Fh Parallel port 1
IRQ 8/0 70h Real-time clock
IRQ 9/1 71h CGA vertical retrace (and other IRQ 2 devices)
IRQ 10/2 72h Reserved
IRQ 11/3 73h Reserved
IRQ 12/4 74h Reserved in AT, auxiliary device on PS/2 systems
IRQ 13/5 75h FPU interrupt
IRQ 14/6 76h Hard disk controller
IRQ 15/7 77h Reserved
Now from what the above lets examine some code and I'll explain why and how all of this play on each other
.
.
.
mov ah,09 <- subroutine 9 which prints a string to the screen
mov dx,offset var <- now where placing the offset of our var in dx thus giving our input address
int 21h <- standard dos interrupt. Refer to the above table and you'll see that according
to the subroutine you use int 21h will act differently
.
.
.
I bet right now your asking yourself what ah and dx are am I right? Well, if you did then good on you. Anyway - there registers.
Registers are a series of memory cells inside the CPU itself. Know that registers make our life's worlds easier. Here why:
To store a value in memory the data has to travel out of the cpu, and wait its turn to get stored in memory. To store a value on the
hard disk the data must travel out of the CPU, into the harddisk controller chip, and wait its turn to be serviced by the hard drive.
Here's a list of registers:
General Registers
AX
BX
CX
DX
Segment Registers
CS <- points to start of the code segment
DS <- points to start of the data segment
ES <- Extra segment pointer
SS <- points to start of stack segment
Pointer Registers
IP <- Instruction pointer
SP <- stack pointer
BP <- base pointer
Data Transfer Registers
SI <- source index
DI <- destination index
To see your registers open a command prompt and type debug.
1.start>run>cmd.exe
2.at the prompt type debug
3.from here type r
4.type q to exit
[OUR FIRST PROGRAM]
Okay now lets bring it all together. I'm going to show you the code then walk you throguh it.
---cut here---
jmp start
;;=======================================
var db "A long ass fucking time ago in a town called kickapoo.$"
;;=======================================
start:
mov ah,09
mov dx,offset var
int 21h
jmp 0
---cut here---
jmp means jump, and is used with in this case the label start
var obviously is our variable that where storing the string, and db
just declares a piece of data. This is the same as in BASIC.
db declares a byte, dw declares a word, and dd declares a Dword.
jmp 0 <- its one of my little shortcuts to end the program and return
control back to dos I could have used 4ch but I just don't.
1. To compile this copy and paste this in notepad.
2. Save the file with a .asm extension
3. go to a command shell and cd your to the dir you have a86 installed upon
(Note:to make your life easier I would suggest writting a batch file in
dir where a86 is at to open a command shell automatically and go to that
location)
---cut here---
command.com
cd desktop\asm <-of course you have to change this to your dir
--cut here---
If you don't know what I'm talking about when I say batch scripting go here:
http://www.onesmartclick.com/programming/batch-files.html
4. Once your at command shell type a86 filename.asm
5. It should produce two files. The com file, and a systems file. Go ahead and del the .sym file
(If you don't know how to do that I suggest you go here:
http://www.computerhope.com/msdos.htm - typing help will also produce a list of commands)
6. Nothing left now but to execute the com file and enjoy the knowledge you just gained.
[WHAT COMES NEXT]
What you did here was stored a string in a variable and printed it to the screen. Next maybe take in the
input from the keyboard or maybe explore cmp command to compare what the user enter's to what is stored in a
variable. Be creative, and don't stop when you hit a wall. Your dealing with the power of your CPU when you
program in assembly so be careful.
If you have any questions or problems send me an email.
00100 ~- DeCtrl -~ 00100
Cast your vote on this article *Note: the order of the votes has been reversed.
Comments: Published: 11 comments.
By: InferiorTerror - 01:04 am Wednesday September 05th, 2007
Nice article. Below is a "Hello World" example.
name "intro"
org 100h
; set video mode
mov ax, 3 ; text mode 80x25, 16 colors
int 10h ; do it!
; cancel blinking and enable all 16 colors:
mov ax, 1003h
mov bx, 0
int 10h
; set segment register:
mov ax, 0b800h
mov ds, ax
; print Hackers Know"
; first byte is ascii code, second byte is color code.
mov [02h], 'H'
mov [04h], 'a'
mov [06h], 'c'
mov [08h], 'k'
mov [0ah], 'e'
mov [0ch], 'r'
mov [0eh], 's'
mov [10h], ','
mov [12h], 'K'
mov [14h], 'n'
mov [16h], 'o'
mov [18h], 'w'
; color all characters:
mov cx, 12 ; number of characters.
mov di, 03h ; start from byte after 'h'
c: mov [di], 11101100b ; light red(1100) on yellow(1110)
add di, 2 ; skip over next ascii code in vga memory.
loop c
; wait for any key press:
mov ah, 0
By: thetrojan01 - 04:47 am Thursday September 06th, 2007
yeap 10/10
By: fitfool - 08:45 pm Thursday September 06th, 2007
Hmm, inferior, are you forgetting a null byte? or is it not needed?
By: c24lightning - 01:43 pm Saturday September 08th, 2007
forget this-im sick and tired of ppl saying in their articles "if u don't have it, download it..." and "you can find it here...". but other than that, good article.
By: DeCtrl - 01:48 pm Saturday September 08th, 2007
Okay so next article I write I'll give you the code without explaning anything or telling you where you can get any of the tools/info (i.e compliers, hex editors, etc.) I was only going to give you so much, but I also wanted you to continue your own study.)
By: weekend hacker - 12:31 pm Sunday September 09th, 2007
who wants to learn a bit more of assembly can learn here http://www.arl.wustl.edu/~lockwood/class/cs306/books/artofasm/toc.html and btw great article 10
PS: loved the part with "A long ass fucking time ago in a town called Kickapoo" Tenacious D are godz :D
This site is the collective work of the
HackThisSite staff. Please don't reproduce in part or whole without permission.
Page Generated: Sun, 12 Oct 2008 23:25:17 -0500 Exec:
9