CS221 Lecture Notes Irvine – Chapters 1.3, 2, Appendix B Let`s

CS221
Lecture Notes
Irvine – Chapters 1.3, 2, Appendix B
Let’s switch gears a little bit and touch on a few items specific to the Intel 8086-based
computers. Here we will introduce assembly language using debug.exe, and then provide
an overview of the Intel architecture.
Introducing Assembly Language
So far in our examples we have been using machine code to represent our instructions.
For example, on the IAS computer we had a 20 bit instruction size, with the first eight
bits representing an opcode and the rest the operand. A value such as 05006 decoded to
“Add” with the memory address of 006.
Rather than use direct bits or hex machine code, assembly language makes the job a bit
easier. An assembly instruction represents a single machine instruction. The assembly
instructions are referred to as mnemonics, a short alphabetic code that means “assist the
memory” to remember the CPU instruction. An assembler handles the task of converting
mnemonics into machine code.
Here are a few sample mnemonic assembly instructions for Intel machines:
CLC
; mnemonic for clear carry bit. Hex machine code: F8
INC AX
; increment AX register by one. Machine code: 40
INC BX
; increment BX register by one. Machine code: 43
MOV AX, 1 ; move number 1 into AX. Code: B8 01 00
MOV AX, 12AB ; move number 12AB into AX. Code: B8 AB 12
Note the reverse byte (“little endian”) order for the operands. What is the op code for
MOV to the AX register? Also note the variable length instruction size.
Also note tha t instructions can be followed by a comment. In this case, comments begin
with a semicolon. This will apply when we start using an assembler but not to debug.
As a reminder, assembly is a low- level language. Each assembly mnemonic maps to an
individual CPU machine code instruction. This is different from a language like C++ or
Java, which typically maps high- level source code into many instructions.
Operands for an instruction can be either of the following:
•
•
•
•
•
Immediate
Variable
Register
Memory address
Indirect address
-
the exact data follows, e.g. the number 10
a variable follows, e.g. a memory operand, direct address
a register follows, e.g. AX
a direct memory address follows, e.g. [0100]
an indirect memory address follows
Using Debug
We can explore some assembly language by playing with a debugger. A debugger is a
program that lets you examine registers and memory, step through a program one
instruction at a time, and even change the contents of memory or instructions as you
please. As the name implies, this can be very useful for debugging programs that you
have written. We can also use it to help learn about how the computer operates and write
some small sample programs.
A nice and simple debugger that comes with all DOS systems is debug.exe. There are
also more sophisticated debuggers (such as the one that comes on the Irvine CD-ROM)
but for now we will use debug to try some sample programs.
To start debug, open up a MS-DOS window and type “debug”. You should be given a
“- “ prompt indicating debug is ready and willing for your commands!
Type “?” to see a list of all commands available:
Here are a few commonly used debug commands:
A (Assemble) – Assembles a program from assembly into machine code. Formats are:
A
A address
e.g. A 100
Assembles at CS:100h
assembled text continues until enter is pressed on a blank line.
G (Go) – Executes a program in memory. Formats are:
G
G breakpoint
G =address
e.g.
G
G =100
G 50
- Executes from the current IP
- Executes from memory location 100
- Execute from current location and stop before offset 50
R (Register) – Displays or manipulates the contents of the registers. Formats are:
R
R register
e.g.
R
R AX
RF
- Displays all registers
- Displays AX and prompts for a new value
- Displays flags and prompts for a new value
A sample is shown above for displaying and changing the contents of the AX register.
The flags are shown in the bottom right corner. Here is a list of valid flags:
Set:
Clear:
OV = Overflow
DN = Direction Down
EI = Interrupts enabled
NG = Sign Flag Neg
ZR = Zero
AC = Aux Carry
PO = Odd Parity
CY = Carry
NV = No overflow
UP = Direction up
DI = Interrupts disabled
PL = Sign flag Pos
NZ = Not Zero
NA = No Aux Carry
PE = Even Parity
NC = No Carry
U (Unassemble) – Translates memory into assembly language mnemonics. Formats:
U
U startaddress
U startaddress endaddress
e.g.
U
- Disassembles the next 32 bytes from the current CS:IP
U 100 - Disassembles the next 32 bytes at CS:100 , address 100
D (Dump) – Displays data as hex and ASCII. Formats:
D
D startaddress
e.g.
D
- Dumps memory from current segment
D 100 - Dumps memory from address 100
T (Trace) – Executes one instruction at a time starting at the current IP. Formats:
T
T count
T =address
e.g.
T
T5
T =100
- Trace the next instruction
- Trace the next 5 instructions
- Trace starting at CS:100
There are many more debug commands, but those are the basics. Let’s go ahead and
write a short assembly program! Remember that when we enter numbers in debug,
all values are by default assumed to be hexadecimal, not decimal.
Here is a small sample program from the textbook:
MOV AX, 5
ADD AX, 10
ADD AX, 20
MOV [0120], AX
INT 20
; move 5 to the AX register
; add 10(hex) to the AX register
; add 20(hex) to the AX register – should hold 35
; Copy AX register to memory address 0120
; Interrupt to halt the program
Here is a trace of entering and executing this program. Let’s enter the program at
memory address 100. Use the “A 100” command to assemble here. Enter the program
followed by a blank line. We can view our code using the “U” command. Then we will
trace through the registers by displaying them using “R” and using the “T” command to
set through the code one line at a time:
Here is a memory dump of the code and also the contents of the registers:
Now let’s start tracing through the program:
Notice how the contents of the accumulator, AX, change as the additions are performed.
If we check the contents of memory we will see that they have been written out as well:
Let’s try one more program. This program will print the words “Hi” to the screen:
MOV AH, 2
MOV DX, 48
INT 21
MOV DX, 69
INT 21
INT 20
; Load AH with the interrupt code for display to console
; Load DX register with ASCII for ‘H’
; Call the DOS interrupt service
; Load DX register with ASCII for ‘i’
; Call the DOS interrupt service
; Terminate the program
You should be able to assemble this program and execute it. It should print out “Hi” to
the console screen.
How does it work? It makes use of DOS Interrupt 21H. This particular interrupt handles
a multitude of I/O tasks. For example, we can use this interrupt handler to input data
from the console, to output data, to read the clock, select the disk, get the date, create
folders, create files, change file attributes, and many many other functions. A complete
list is available on the class web page. To select which function we want, we have to
load particular registers with the proper data. In this case, if we load AH with the value
2, this tells the interrupt handler that we want to print to the console. Whatever ASCII
data is located in the DX register gets printed.
INT 21 and INT 20 are interrupt handlers available to us and comprise part of the
interrupt vector. The interrupt vector comprises several memory locations that contain
addresses of interrupt handlers. These interrupt handlers are loaded by the operating
system or by the BIOS or other hardware devices. Appendix G of the Irvine textbook
lists some of these interrupt lists. They include BIOS, memory, disk, keyboard, ROM,
printer, video, and other services.
Intel Hardware and Software Architecture
The Intel family of microprocessors is quite diverse. For the majority of this class we
will focus on the 16 bit Intel 8086 processor. However we will look a little bit at more
recent versions of the chip. The latest incarnation, the Itanium, is the first of a
completely new architecture that emulates the 8086.
The registers inside the 8086 are all 16 bits. As described earlier, they are split up into
four categories: General Purpose, Index, Status & Control, and Segment.
General Purpose Registers
The four general purpose registers are the AX, BX, CX, and DX registers.
AX - accumulator, and preferred for most operations.
BX - base register, typically used to hold the address of a procedure or variable.
CX - count register, typically used for looping.
DX - data register, typically used for multiplication and division.
All of the general purpose registers can be treated as a 16 bit quantity or as two 8 bit
quantities. The high byte is referenced by replacing the X with H. The low byte is
referenced by replacing the X with L:
AX
AH
15
AL
8
7
0
For example, putting 0xF100 into AX is the same as putting F1 into AH, and then 00 into
AL. We can reference DX in terms of DH, DL, CX in terms of CH, CL, and BX in terms
of BH, BL as well.
Segment Registers
The CPU contains four segment registers, used as base locations for program instructions,
data, or the stack. In fact, all references to memory on the IBM PC involve a segment
register as a base location.
The registers are:
CS – Code Segment, base location of program code
DS – Data Segment, base location for variables
SS – Stack Segment. Base location of the stack
ES – Extra Segment. Additional base location for variables in memory.
Index Registers
The index registers contain offsets from a segment register for information we are
interested about. There are four index registers:
BP – Base Pointer, offset from SS register to locate variables on the stack
SP – Stack Pointer, offset from SS register as to the location of the stack’s top
SI – Source Index, used for copying strings, segment register varies
DI – Destination Index, used for destination for copying strings
Calculating Addresses
How are these registers used to calculate addresses? In real mode on the Intel 8086,
there is a 20 bit address bus and the capability to address up to 1MB of memory.
However, registers are only 16 bits long. This means we can only address 64K of
memory using a 16 bit register.
To solve this problem, the CPU computes 20 bit absolute addresses by combining the
segment with the offset (i.e. index).
Segmented addresses are represented by:
BaseSegment:Offset
e.g.:
08F0:0010
Absolute addresses are represented directly by the hex representing the 20 bits:
e.g.:
0AB41
How do we compute an absolute address given a segmented address? Note that in the
segmented address we have a total of 32 bits. This is an additional 12 bits than we really
need! The scheme to compute the absolute address is to multiply the segment by 16 (i.e.
slide it over four bits to the left) and then add the result to the offset:
e.g. given 08F1:0010
here the segment is 08F1
multiply by 16 or shift four bits / one hex digit to the left, inserting a zero on the right:
giving: 08F10
now add to the offset:
08F10
+
0010
-----------------08F20
ß Absolute address
By sliding the segment over by four bits, we get a total addressable space of 20 bits.
Note that there is overlap among segments:
08F10
+
0000
-----------------08F10
08F00
+
0010
-----------------08F10
That is, 08F1:0000 and 08F0:0010 both reference the same absolute address.
You might wonder why such a complicated addressing method is used. One reason is
surely to confuse CS students. Another is that this allows the CPU to access the 20 bit
address bus using the 16 bit registers. A benefit of the scheme is that it becomes compact
and easy to reference data within a single segment. Another benefit is that it allows
programs to be loaded into any segment address without having to recalculate the
individual addresses of variables – they are merely references as offsets from the
segment. Finally, programs can access large data structures by gradually modifying the
segment portion of the address to access large blocks of memory. In this case, the
overlap feature of the segment becomes useful. A downside of the scheme, in addition to
the complexity, is the confusion that can result if a program needs to access data beyond
a 64K block of memory.
Status and Control Registers
The last set of registers is the Instruction Pointer and the Flags:
IP – Instruction pointer, offset from the CS for the next instruction to execute
Flags – contains status flags
These flags are:
Direction: Used for block transfer of data, may be 0=up or 1=down
Interrupt: 1 = enabled, 0=disabled
Trap: Determines if the CPU should halt after each instruction. 1=on, 0=off.
Carry: Set if the last arithmetic operation had a carry
Overflow: Set if the last arithmetic operation overflowed
Sign: Set if the last arithmetic operation was negative. 1=negative, 0=positive
Zero: Set if the last arithmetic operation generated a result of zero. 1=zero
Aux Carry: Set when a carry from bit 3 to bit 4
Parity: Used for a parity check, number of 1’s
Intel Microprocessor History
The following is a brief history of the different Intel microprocessors:
8086 (1976)
16 bit data bus, 16 bit address bus
segmented memory model
8088 (1980)
Identical to 8086 but 8 bit data bus instead of 16 bit data bus
Used in IBM PC
8087
Math co-processor chip introduced to speed up floating point calculations
80286
Used in IBM AT
24 bit address bus, 16 bit data bus
Protected mode – OS could protect programs in separate memory segments
80386 (1985)
32 bit registers, 24 bit address bus
32 bit register accessible via extra “E”, e.g. “EAX”, “EBX”, “ESP”…
80386 – DX 32 bit data bus
80386 – SX 16 bit data bus
Supported virtual mode memory, “virtual machines”, “virtual memory”
Paging
80486
486SX - No floating point unit , unlike the 486DX with integrated FPU
Could decode/execute 5 instructions at once
8K level-1 cache for both instructions and data
Pentium
Legal issues with 586
Separate 8K caches for data, instructions
Branch prediction
32 bit address bus
MMX - perform integer operations on vectors of 8, 16, or 32 bit words
Pentium Pro
multiple branch prediction
speculative execution
register renaming
“P6” core
Pentium II (1997)
P6 core with MMX instructions
Processor card (SEC) instead of IC package
Higher frequency components, fewer pins
Marketing reasons?
Celeron
Pentium II with no (or smaller) L2 cache
Positioning for low-end market
Pentium III
Streaming SIMD Extensions (SSE)
Perform float operations on vectors of up to 32 bit words
Eight 128-bit registers to contain four 32-bit ints or floats
On-die cache
Pentium IV
Multiple ALU’s
Trace cache
SSE2
Redesign to allow higher clock rate
Itanium
EPIC - Explicit Parallel Instruction Computing
128 bit registers, data bus
41-bit instructions in 128 bit bundles of three plus five "template bits" which
indicate dependencies or types
Operating System and Memory
The 1Mb of accessible memory in the 8086 ranges from 00000 to FFFFF. RAM
occupies 0000 – BFFFF. ROM occupies C0000 to FFFFF. DOS uses the first 640K of
memory, 0000 to 9FFFF.
Memory usage is illustrated in the table below:
Address
00000
00400
9FFFF
A0000
B8000
C0000
F0000
Contents
Interrupt Vector Table
DOS Data
Software BIOS
DOS Kernel Device Drivers
COMMAND.COM
Available to programs
Used by COMMAND.COM
Video Graphics Buffer
Text Buffer
Reserved
ROM BIOS
The interrupt vectors are used to process hardware and software interrupts. This
comprises the first 1024 bytes of memory. These locations store addresses of interrupt
handlers for the respective routines.
The BIOS (Basic Input/Output System) includes routines for managing the keyboard,
screen, clock, detecting PlugAndPlay devices, and other hardware devices. This is
typically done through firmware – software burned onto the BIOS chip as hardware.
The DOS kernel includes services for disk and program functions, such as loading and
running user programs. Above the kernel are the resident parts of MS-DOS to interpret
basic commands typed from the DOS prompt.
All of these are loaded when your system boots up. The ROM BIOS tells how to load the
boot record from the device, which in turn loads the COMMAND.COM information into
memory along with all of the device drivers.
The video graphics buffer is memory for what is called a memory-mapped video
display. Locations in memory correspond to pixels on the graphics screen or to
characters on the text screen. The video memory area is special high-speed VRAM
(video RAM). Text mode VRAM is at address B8000 and graphics mode VRAM is at
address A0000. Many applications write directly to the VRAM to output data. Other
programs invoke DOS routines that output data to the appropriate VRAM for you.
Microcomputer Components
Briefly, the components found inside Intel-based microcomputers are as follows. For
more detail, see chapter 2.4 of Irvine.
Motherboard
CPU socket or slot
Coprocessor socket
Cache memory slot
SIMM or DIMM slots for main memory
ROM BIOS socket
Serial, mouse, parallel, IDE or SCSI drive connectors and controllers
Many motherboards now come with integrated sound, graphics, and network
Buses
PC AT Bus
ISA Bus
EISA Bus
MCA
VESA
PCI
- 8Mhz bus, 16 bit data, 24 bit address
- Standardized 8Mh bus
- Extended Industry Standard Association
Suported 32 bit data transfer, burst mode
- Proprietary IBM microchannels
- Video Electronics Standards Association
Higher speed bus for graphics
- Peripheral Component Interconnect
32-64 bit bus up to 100Mhz still predominant today in PCs
Video
Main components are the video controller and amount of video memory
Pixels are drawn using raster scanning. An electron gun refreshes the screen elft
to right, top to bottom. Interlaced mode only scans every other line, while noninterlaced scans every line. Non- interlaced produces less flicker although higher
resolutions are typically possible in interlaced mode.
Memory
VRAM – Video RAM
CMOS RAM - Used to system setup information, time, date.
Requires less power, can be operated off a battery
DRAM – Dynamic RAM used for main memory today
EDO RAM – Enhanced Data Out
Remembered previous access, faster on subsequent locations
SDRAM – Synchronous Dynamic RAM
Synchronized with clock, can handle fast bus speeds
SRAM – Static RAM used for high-speed memory such as level 2 caches
Typically connected directly to the microprocessor bus
Typical sizes are 128K to 512K
SIMMs – Small Inline Memory Modules, package w/32 bit data path
DIMMs – Dual Inline Memory Modules, 64 bit data path
Secondary Storage
Disk, Hard drive, CDROM, CDR/W, Zip
IDE – Intelligent Drive Electronics. 8MB/s transfer rate
Found in most earlier hard drives, only up to two drives
EIDE – Enhanced IDE. Supports more than two drives
DMA, up to 33MB/sec , bigger drives
SCSI – Small Computer Systems Interface
Faster, more flexible than IDE, more expensive
Other
PC/AT keyboard or PS/2 keyboard
Mouse, serial or bus mouse
Expansion slots
Power supply
Parallel/Serial port