Compared with the VSC the x86 family of microprocessors have an extensive set of registers. They have a minimum of 14 internal 16-bit registers, some of which can be accessed as two different 8-bit registers. For example AX, BX, CX and DX are word (16-bit) registers. AL, AH, BL, BH, CL, CH, DL and DH are byte (8-bit) registers. The L means low byte and and H means high byte. Actually AX through DX are each made up of the register pairs (AL,AH) through (DL,DH). There are 10 more registers that are each 16 bits.
Assembly language uses mnemonics which are short strings representing machine language instructions. Assembly programs are made of lists of mnemonics and operands as shown in the examples below:
Common Assembly Instructions
|
Transfers
a byte or word from source to
destination. The source can be a register, an immediate number,
or
an address. The destination can be a register or an address.
MOV AX,BX copies BX to AX MOV DL,CL copies CL to DL MOV BL,[BX] copies the contents of the memory at address BX to BL |
INT | Transfers
program to a procedure specified
by the interrupt number. The interrupt returns processing to the
address after the INT instruction.
INT 20h executes interrupt 20 hex (.COM exit interrupt) INT 16h executes interrupt 16 hex (keyboard interrupt) INT 10h executes interrupt 10 hex (screen interrupt) |
JMP | Transfers
program to address
JMP 12:34 jumps to segment 12, offset 34 |
LOOP | Decrements
CX transfers program to address
if CX>0, if CX=0 transfers program to next instruction
|
INC | Increments
a register by 1.
INC CL CL now equals 43 |
DEC | Decrements
a register by 1.
INC CL CL now equals 41 |
Running a Simple Assembly Language Program
We will investigate the CPU using a simple version of machine lanugage programs called .COM files. These files are created using the utility program DEBUG. This program allows you to write, edit, trace, load and save 80x86 assembly programs.
Step 1: Open an MS-DOS prompt window, go to the directory containing the DEBUG program (this could be C:\windows\command). From the command console (once you are in the correct directory), run the DEBUG utility by typing its name at the prompt and pressing the <Enter> key.
Step 2: You should see a dash on the screen. Now enterStep 3: Enter the following program (press enter at the end of each line)
Step 4: Now enter
Step 5: Type Q and press <Enter> to quit DEBUG.
Let's take a closer look at what this program is doing. The program loads the DL register with 24 hex. All numbers in DEBUG are hex by default. The ASCII value of the symbol $ is 24 hex. Then the program places the value 2 in the AH register. The DOS operating system and its legacy as provided in the Win32 OS family supports the DOS interrupt INT 21. This interrupt checks the value in AH to see what action is to be performed. The 2 instructs the processor to run a section of code to print a character to the screen memory. Finally the INT 20 causes an exit (ends the .COM program)
Viewing Register Contents and Listing .COM programs
From the DEBUG utility you can check the values of the registers using the R command. Run DEBUG and enter -R at the dash. You should see a list of register names and hex values for each.
You can view any portion of memory using the U command. To view a page of the contents of memory at a particular location simply enter the command followed by the starting address
-U100
Notice that the upper 16 bits of the address is assumed to be the current address. We can specify any other location in memory by including the complete address
-U 1234:1234
You can also specify a range of addresses by including the starting and ending address separated by commas.
-U 1000, 1010
When using the U command every word is interpreted as an assembly language instruction. When the contents of a memory address cannot be interpreted as an instruction the U command displays questions marks ???. Alternatively we can view the contents of memory as data (in hex) by using the D command.
-D100
Each pair of hexadecimal digits
is one byte, and
each line
shows 16 bytes. Note that the address changes by 10 hex or 16
decimal.
The block on the right-hand side shows the equivalent ASCII symbol for
each byte in the range 0..127 decimal.
Printing Messages to the Screen
If you wanted to print messages to the screen it would be rather cumbersome to print one character at a time. Instead we can Set AH=9 to instruct the DOS interrupt INT 21 to print an entire string.
You can invoke a carriage return using the ASCII value 10 (A hex) and a linefeed using the ASCII value 13 (D) as shown below,
Indirect Addressing Mode
To place the number 9 hex into offset address 200 hex, we load the address 200h into BX, load the value 9 into AL and the transfer the value AL into the memory location pointed to by BX.
Now try this.
Saving Programs
The DEBUG program can be saved
to the hard drive by following the procedure outlined below:
1. Set the BX register to 0.2. Set the CX register to the number of bytes contained in the program.
3. Use the N command to name the program.
4. Use the W command to write the program to the hard drive.
The BX and CX registers can be set
to any value by using the R command. Typing the command
RBX
causes the DEBUG utility to display the contents of this register and wait for you to enter a new value. To keep the present value just press the <Enter> key. Otherwise enter the new value. In this case you will want to enter a 0 value.
Next set the CX register to the number of bytes contained in the program being saved. You can set this register to a value that is larger than the program size but this is not recommended.
Now set the name of the program to be saved using the N command
-Ntest.com
You can save .COM files to the A: drive by including the drive letter as part of the file name.
-NA:test.com
Finally you can write the file
to the designated
drive by using the W command. To retrieve the saved program set
the
name and then enter L (load command).
Interacting with the .COM Program During Execution
Write and run the mystery .COM program below and then use the <Cntrl><Break> command to interrupt it. For Windows 2000 you can stop the program with a <Cntrl> C. If you touch any other key you may have to close the console window to interrupt this program.
-RIP
100
You can specify a breakpoint to stop the program by including the breakpoint address following the G command.
-G 102
When the breakpoint is reached the values of the registers are displayed to support diagnostics. Setting breakpoints is a good way to view the contents of the registers before they are reset on exit.
More Assembly Instructions
|
Transfers
a byte or word from an external
port to AX. If the port value is greater than FF hex, then it
must
be placed in register DX.
IN AX, B3 sends contents of 16-bit port B3 to AX MOV DX,FB00 IN AL,DX sends contents of 8-bit port FB00 to AL |
|
Transfers
a byte or work from AL or AX
to an external port. If the port value is greater than FF hex,
then
it must first be placed in register DX.
OUT B3, AX sends contents of AX to 16-bit port B3 MOV DX,FB00 OUT DX, AL sends contents of AL to 8-bit port FB00 |
XCHG | Exchanges
the contents of two 8 or 16-bit
registers.
XCHG AX,BX |
CMP | Compares a
register or an immediate byte
or word with a register by performing a SUB operation. The flag
register
is set based on the result. The result is discarded.
CMP AX, BX zero flag set if AX=BX |
TEST | Tests a
register or an immediate byte
or word with a register by performing an AND opera;tion. The flag
register is set based on the result. The result is discarded.
TEST AX, BX zero flag set if AX=BX |
JE JNE JL JGE JLE |
Jumps to
an address if a CMP insruction
produced a destination equal to a source.
JG 1234 jumps to address 1234 if AX>13 JE 1234 jumps to address 1234 if AX=13 JNE 1234 jumps to address 1234 if AX/=13 JL 1234 jumps to address 1234 if AX<13 JGE 1234 jumps to address 1234 if AX>=13 JLE 1234 jumps to address 1234 if AX<=13 |
|
Rotates
the register right by 1 bit.
The LSB wraps over to the MSB. If more than 1 bit needs to be
rotated,
set the number of bits to rotate in the CL register first
MOV AX,0083 this is 0000 0000 1000 0011 |
|
Rotates
the register left by 1 bit.
The MSB wraps over to the LSB. If more than 1 bit needs to be
rotated,
set the number of bits to rotate in the CL register first.
MOV AL,83 sets AX = 0000 0000 1000 0011 |
|
Shifts the
register right by 1 bit.
The LSB is lost, the MSB is loaded with a 0 bit.
MOV AX,F002 sets AX = 1111 0000 0000 0010 |
|
Shifts the
register left by 1 bit.
The MSB is lost, the LSB is loaded with a 0 bit.
MOV AX,0083 sets AX = 0000 0000 1000 0011 |
|
Performs a
Boolean AND operation.
The result is stored in the destination register.
MOV AX,1234 sets AX = 0001 0010 0011 0100 |
|
Perfoms a
Boolean OR operation.
The result is stored in the destination register.
MOV AX,1234 sets AX = 0001 0010 0011 0100 |
|
Performs a
Boolean Exclusive OR operation.
The result is stored in the destination register.
MOV AX,1234 sets AX = 0001 0010 0011 0100 |
|
Performs a
Boolean NOT operation on the
specified register (one's complement)
MOV AX,1234 sets AX = 0001 0010 0011 0100 |
|
Adds a
source to a destination.
The results is stored in the destination register
ADD AX,13 replaces AX with 13 added to AX |
SUB | Subtracts
a source from a destination.
The result is stored in the destination register.
SUB AX,13 replaces AX with AX minus 13 |
|
(byte
version) Multiplies AL by
a source value. The source can be a register or an address The
result
will be stored in AX.
(word version) Multiplis AX by a source value. The source can be a register or an address. The high 16-bit result is stored in DX, the low 16-bit result is stored in AX. MUL DL multiplies AX by DL result is in AX |
|
(byte
version) Divides AX by an 8-bit
source value. The source can be a register or an address.
The
result is stored in AX. The quotient is in AL, and the remainder
is in AH.
(word version) Divides AX by a 16-bit source value. The source can be a register or an address. The quotient is placed in AX, and the remainder is placed in DX. DIV DL divides AX by DL quotient is in AL, |