Assembly Language & the CPU
Download
Report
Transcript Assembly Language & the CPU
Computing Machinery
Intel x86 - Assembly Language
x86 Intel Series Microprocessor Registers
Registers
AX = AH,AL - accumulator
BX = BH,BL - base register
CX = CH,CL - counter
DX = DH,DL - data register
EAX - 32 bit version of the accumulator
EBX - 32 bit version of the base register
ECX - 32 bit version of the counter
EDX - 32 bit version of the data register
SI - source index register
DI - destination index register
BP
SP
IP
ZF
CF
OF
SF
IF
-
base pointer (used to access the stack)
stack pointer
instruction pointer (points to next instruction)
zero flag
carry flag
overflow flag
sign flag (0 = non-negative, 1 = negative)
interrupt flag (0 = reset, 1 = set)
The EFLAGS register holds the operating state of the processor. These values are changed by
the execution of machine language instruction. Each bit gives the state of a specific parameter
relative to the last instruction executed.
Bit
Label
0
CF
2
PF
4
AF
6
ZF
7
SF
8
TF
9
IF
10
DF
11
OF
12-13 IOPL
14
NT
16
RF
17
VM
18
AC
19
VIF
20
VIP
21
ID
Desciption
.
Carry flag
Parity flag
Auxiliary carry flag
Zero flag
Sign flag
Trap flag
Interrupt enable flag
Direction flag
Overflow flag
I/O Priviledge level
Nested task flag
Resume flag
Virtual 8086 mode flag
Alignment check flag (486+)
Virtual interrupt flag
Virtual interrupt pending flag
ID flag
"Secret" Registers
Some of the registers provided on the x86 (since the 386) by Intel are not well documented.
These registers include control registers, debug registers, test registers and protected mode
segmentation registers. The Control Registers are labeled CR0 through CR4. The Debug
Registers are DR0 through DR7. The Test Registers (removed from the Pentium) are labeled TR3
through TR7. There are also protected mode segmentation registers, called the Global Descriptior
Table Register (GDTR), the Interrupt Descriptor Table Register (IDTR), the Local DTR (LDTR)
and the Table Register (TR).
Running a Simple Assembly Language Program
Step 1: Open an MS-DOS prompt window, go to the directory containing the DEBUG program
(this could be C:\windows\command). For those of you reared on Microsoft Windows Look in
the Programs directory under Startf ro MS-DOS Prompt. If you are using an old version of
Windows you should find the DEBUG utility in the c:\windows\command directory. From a
DOS prompt, enter,
cd c:\windows\command
For Windows 2000 you may need to go to
the c:\winnt\system32 directory. You can
obtain a command console on a Windows
XP machine by running CMD from the
RUN utility under START.
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.
or whereever the DEBUG utility is found.
Step 2: You should see a dash on the screen. Now enter
-A100
(the dash - is already on the screen, so you don't have to enter it). This tells your program to
begin at address 100 hex. All .COM files are loaded at address 100 hex. You should see two
groups of four digits (hex) separated by a colon. This is the actual address at which you will be
entering your assembly program.
Step 3: Enter the following program (press enter at the end of each line)
MOV DL, 24
MOV AH, 2
INT 21
INT 20
Now press an extra carriage return to return to the dash prompt.
Step 4: Now enter
G106
This will run the program and through address ...106 and then display the contents of the
CPU registers.
Step 5: Run the program again but this time just enter -G. The program runs and then
terminates normally. In order to see the contents of the registers, we need to use the -R
command. However, since the program was permitted to complete the registers are
automatically cleared.
To see the program stored in memory, enter -d100 which will display the contents of memory
starting at address ...100. To quit DEBUG, enter Q.
Viewing Assembly Code
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
You can also specify a range of addresses by included the starting and ending address separated
by commas.
-U 1000, 1010
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.
100
102
105
107
109
MOV AH,9
MOV DX,109
INT 21
INT 20
DB 'This is a sample string.$'
Enter and run this program. If we view the source code using the U command the string is
interpreted as a sequence of assembly lanauge instructions. It is sometimes preferred to use the D
command and view the code as data.
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,
100 MOV AH,9
102 MOV DX,109
105 INT 21
107 INT 20
109 DB 'This is',A,D,'a sample string.$'
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.
MOV
MOV
MOV
INT
BX, 200
AL, 09
[BX], AL
20
We can check to see if the value 9 was placed at offset address 200 by calling the command
-D200.
Saving Programs to Disk
The DEBUG program can be saved to disk 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 disk.
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.
100
102
104
106
MOV
MOV
INT
JMP
AH,2
DL,24
21
104
Before restarting the program you may want to reset the instruction pointer register (program
counter) to 100 using the command,
-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.
MOV Instruction
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
MOV
MOV
MOV
AL,13
AX,BX
DL,CL
BL,[BX]
copies
copies
copies
copies
13 to AL
BX to AX
CL to DL
the contents of the memory at address BX to BL
INT Instruction
Transfers program to a procedure specified by the interrupt number.
processing to the address after the INT instruction.
INT
INT
INT
INT
21h
20h
16h
10h
executes
executes
executes
executes
interrupt
interrupt
interrupt
interrupt
21
20
16
10
hex
hex
hex
hex
The interrupt returns
(DOS interrupt)
(.COM exit interrupt)
(keyboard interrupt)
(screen interrupt)
JMP Instruction
Transfers program to address
JMP 1234
JMP 12:34
jumps to offset address 1234
jumps to segment 12, offset 34
LOOP Instruction
Decements CX, and then transfers program to address if CX>0. If CX=0 transfers program to next
instruction
LOOP 1234
loops to offset address 1234
INC Instruction
Increments a register by 1.
MOV CL, 42
INC CL
CL now equals 43
DEC Instruction
Decrements a register by 1.
MOV CL, 42
INC CL
CL now equals 41
IN Instruction
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 AL, 13
IN AX, B3
MOV DX,FB00
IN AL,DX
sends contents of 8-bit port 13 to AL
sends contents of 16-bit port B3 to AX
sends contents of 8-bit port FB00 to AL
OUT Instruction
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
OUT
MOV
OUT
13, AL
B3, AX
DX,FB00
DX, AL
sends contents of AL to 8-bit port 13
sends contents of AX to 16-bit port B3
sends contents of AL to 8-bit port FB00
XCHG Instruction
Exchanges the contents of two 8 or 16-bit registers.
XCHG AL, DH
XCHG AX,BX
CMP Instruction
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 AL, 13
CMP AX, BX
zero flag set if AL=13
zero flag set if AX=BX
TEST Instruction
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 AL, 13
TEST AX, BX
zero flag set if AL=13
zero flag set if AX=BX
'JUMP' Instructions
Jumps to an address if a CMP instruction produced a destination equal to a source.
CMP AX, 13
JG 1234
JE 1234
JNE 1234
JL 1234
JGE 1234
JLE 1234
jumps
jumps
jumps
jumps
jumps
jumps
to
to
to
to
to
to
address
address
address
address
address
address
1234
1234
1234
1234
1234
1234
if
if
if
if
if
if
AX>13
AX=13
AX/=13
AX<13
AX>=13
AX<=13
ROR Instruction
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
ROR AX,1
this is 0000 0000 1000 0011
now AX= 1000 0000 0100 0001
MOV AL,83
MOV CL,2
ROR AL,CL
this is 1000 0011
now AL= 1110 0000
ROL Instruction
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
ROL AX,1
sets AX = 0000 0000 1000 0011
now AX = 0000 0001 0000 0110
MOV AX,0083
MOV CL,2
ROL AX,CL
sets AX = 0000 0000 1000 0011
now
AX = 0000 0010 0000 1100
SHR Instruction
Shifts the register right by 1 bit. The LSB is lost, the MSB is loaded with a 0 bit.
MOV AX,F002
SHR AX,1
sets AX = 1111 0000 0000 0010
sets AX = 0111 1000 0000 0001
MOV AX,F002
MOV CL,2
SHR AX,CL
sets AX = 1111 0000 0000 0010
sets AX = 0011 1100 0000 0000
SHL Instruction
Shifts the register left by 1 bit. The MSB is lost, the LSB is loaded with a 0 bit.
MOV AX,0083
SHL AX,1
sets AX = 0000 0000 1000 0011
sets AX = 0000 0001 0000 0110
MOV AX,0083
MOV CL,2
SHL AL,CL
sets AX = 0000 0000 1000 0011
sets AX = 0000 0000 0000 1100
AND Instruction
Performs a Boolean AND operation. The result is stored in the destination register.
MOV AX,1234
MOV BX,ABCD
AND AX,BX
sets AX = 0001 0010 0011 0100
sets BX = 1010 1011 1100 1101
sets AX = 0000 0010 0000 0100
OR Instruction
Perfoms a Boolean OR operation. The result is stored in the destination register.
MOV AX,1234
MOV BX,ABCD
OR BX,AX
sets AX = 0001 0010 0011 0100
sets BX = 1010 1011 1100 1101
sets BX = 1011 1011 1111 1101
XOR Instruction
Performs a Boolean Exclusive OR operation. The result is stored in the destination register.
MOV AX,1234
MOV BX,ABCD
XOR AX,BX
sets AX = 0001 0010 0011 0100
sets BX = 1010 1011 1100 1101
sets AX = 1011 1001 1111 1001
NOT Instruction
Performs a Boolean NOT operation on the specified register (one's complement)
MOV AX,1234
NOT AX
sets AX = 0001 0010 0011 0100
sets BX = 1110 1101 1100 1011
ADD Instruction
Adds a source to a destination. The results is stored in the destination register
ADD AX,13
ADD AL,DL
replaces AX with 13 added to AX
replaces AL with AL added to DL
SUB Instruction
Subtracts a source from a destination. The result is stored in the destination register.
SUB AX,13
SUB AL,DL
replaces AX with AX minus 13
replaces AL with AL minus DL
MUL Instruction
(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
MUL BX
multiplies AX by DL result is in AX
multiplies AX by BX result is in DX,AX
DIV Instruction
(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
DIV BX
divides AX by DL quotient is in AL,
remainder is in AH
divides AX by BX quotient is in AX,
remainder is in DX
I/O Ports
A port that is common to all Intel based PCs is the parallel (printer) port. Many PC's have more
than one printer port, labeled LPT1, LPT2 and LPT3 for example. The address for these ports is
not the same for all computers, but we can determine these addresses for a particular computer by
checking the values at memory segment 40hex, beginning at offset 8. From the DEBUG utility
enter the command,
D40:8
The address for LPT1 is therefore 378hex (high byte follows low byte) the next 4 bytes are 00 00
00 00 so there is only one printer port on this system.
We can check to see of the printer (dot-matrix only) is working and ready to print. We can test the
ACK pin for a value of 1 to verify that the printer is on and there are no errors. The pin will equal
0 if the printer is off or if there is an error. The ACK is bit 5 of port 2.
100
103
104
MOV DX, 378
IN AL,DX
INT 20
Since AL=04hex (0000 0100 binary) we see that bit 5 is zero. Let's look at a short assembly
program to display the contents of a register DL to the screen in hexidecimal symbols (i.e.
ASCII characters).
MOV
MOV
MOV
SHR
ADD
CMP
DL,A9
DH,DL
CL,4
DL,CL
DL,30
DL,39
JLE
ADD
MOV
INT
MOV
AND
ADD
CMP
JLE
ADD
MOV
INT
INT
113
DL,7
AH,02
21
DL,DH
DL,0F
DL,30
DL,39
127
DL,7
AH,02
21
20
;loads DL with the value A9 (1010 1001)
;copies DL into DH
;will be used to shift DL 4 bits to the right
;DL now contains the upper nibble (0000 1010)
;adds 30hex to DL (ASCII value) (0011 1010)
;if symbol is >9 we need to add 7 this skips over
;the symbols between 0..9 and A..Z in ASCII table
;this is offset address 113
;DOS interrupt to print to screen
;recover original value in DL
;leaves lower nibble of DL
;converts to ASCII value
;same test as on previous symbol
;this is offset address 127
;DOS interrupt to print to screen
;terminates program
Whew! All this to display two characters to the screen. It doesn't get any more exciting than
this...unfortunately.
"I could sit in an insurance seminar for days with a big
smile on my face.. and they would ask me, 'How can you
stand it?' I would say, 'Because I've programmed in
assembly, I can take anything!' "
-- bonus point for original context of this paraphrase.