CS 630: Advanced Microcomputer Programming Spring 2004 Professor Allan B. Cruse

advertisement
CS 630: Advanced
Microcomputer Programming
Spring 2004
Professor Allan B. Cruse
University of San Francisco
Course Synopsis
•
•
•
•
•
•
We study the IA32 processor architecture
It’s implemented in our Pentium 4 CPUs
Also implemented in some earlier CPUs
Not only Intel, but also AMD, Cyrix, clones
Even present as ‘legacy mode’ in AMD64
For study purposes we can pretend we’re
studying a ‘bare machine’ (i.e., no OS)
Point-of-View
• For study purposes we can pretend we’re
studying a ‘bare machine’ (i.e., it just has
standard PC hardware for doing I/O, and
ROM-BIOS firmware supplied by vendor,
but lacks any operating system software.
• So we get to ‘build our own’ miniature OS
• Doing this will bring us face-to-face with
the CPU’s most fundamental capabilities
Methodology
• Our interactive computer classroom lets us
take a ‘hands on’ approach to our studies
(i.e., we combine ‘theory’ with ‘practice’)
• Typically we’ll devote first part each class
to a ‘lecture’ about aspects of IA32 theory
• Then we’ll take time in the second part of
class for ‘laboratory exercises’ that put the
newly learned ideas into program code
Prerequisites
• Experience with C / C++ programming
• Familiarity with use of Linux / UNIX OS
• Acquaintance with x86 assembly language
– Knowledge of the x86 general registers
– Awareness of the x86’s instruction-set
• Understand the CPU’s fetch-execute cycle
• Recall the ways memory is addressed
Review of System Diagram
Central
Processing
Unit
Main
Memory
system bus
I/O
device
I/O
device
I/O
device
I/O
device
Review of the x86 API
EAX
CS
EBX
DS
ECX
ES
EDX
FS
ESI
GS
EDI
SS
EBP
ESP
General Registers (32-bits)
Segment Registers (16-bits)
EIP
EFLAGS
Program Control and Status Registers (32 bits)
Review of Instruction-Set
•
•
•
•
•
•
•
Data-transfer instructions (mov, xchg, …)
Control-transfer instructions (jmp, call, …)
Arithmetic/Logic instructions (add, or, …)
Shift/Rotate instructions (shr, rol, …)
String-manipulation instructions (movs, …)
Processor-control instructions (cli, hlt, …)
Floating-point instructions (fldpi, fmul, …)
Review “Fetch-Execute” Cycle
main memory
central processor
Temporary
Storage
(STACK)
ESP
Program
Variables
(DATA)
Program
Instructions
(TEXT)
EAX
EAX
EAX
EAX
EIP
the system bus
Review of memory addressing
• Implicit addressing
(e.g. push eax, scasb, xlat, …)
• Direct addressing
(e.g., inc salary, mov counter,#0, …)
• Indirect addressing
(e.g., add [ebx],cl , pop word [bx+si]
Course Textbook
• Tom Shanley, Protected Mode Software
Architecture, Addison-Wesley (1996)
Initial reading assignment:
Week 1: Read Part One (Chapters 1-3)
Week 2: Read Part Two (Chapters 4-5)
Instructor Contact Information
•
•
•
•
Office: Harney Science Center – 212
Hours: Mon-Wed 2:30pm-4:00pm
Phone: (415) 422-6562
Email: cruse@usfca.edu
• Webpage: nexus.cs.usfca.edu/~cruse
CPU Execution Modes
POWER-ON / RESET
REAL
MODE
PROTECTED
MODE
SYSTEM
MANAGEMENT
MODE
VIRTUAL
8086
MODE
Early Intel Processors
•
•
•
•
•
•
•
1971: 4004 (first 4-bit processor)
1972: 8008 (first 8-bit processor)
1974: 8080 (widely used by CP/M)
1978: 8086/8088 (first 16-bit processor)
1982: 80286: (introduced protected mode)
1985: 80386: (first 32-bit processor)
1989: 80486: (integrated floating-point)
Recent Intel Processors
•
•
•
•
•
•
•
•
1993: Pentium processor (dual CPUs)
1995: Pentium Pro (for high-end servers)
1996: Pentium II (single-edge connector)
1998: Pentium II Xeon (multiple CPUs)
1999: Celeron (stripped down Pentium II)
1999: Pentium III (1GHz, 512K L2 cache)
1999: Pentium III Xeon (high-end servers)
2000: Pentium 4 (new SIMD instructions)
Backward Compatibility
• From its first commercial success onward,
“backward compatibility” (i.e., support for
the software legacy) has been viewed by
Intel as an engineering design imperative
• So the first 16-bit processors (8086/8088),
used in IBM-PCs, were designed in a way
that would let them run the vast number of
CP/M programs written for 8-bit 8080 CPU
Real Mode
• 8086/8088 had only one execution mode
• It used “segmented” memory-addressing
• Physical memory on 8086 was subdivided
into overlapping “segments” of fixed-size
• The length of any “segment” was 64KB, to
match the size of an 8080s address-space
• This scheme supported CP/M applications
• (Our Pentium CPUs continue this support)
64KB Memory-Segments
• Fixed-size segments partially overlap
• Segments start on paragraph boundaries
• Segment-registers serve as “selectors”
stack
data
code
SS
DS
CS
Real-Mode Address-Translation
Logical address:
0x12340
+ 0x06789
---------------0x18AC9
16-bit segment-address
16-bit offset-address
0x1234
0x6789
x 16
+
20-bit bus-address
Physical address:
0x18AC9
Protected Mode
• Any Pentium CPU starts up in ‘Real Mode’
• While in real mode, its behavior is like an 8086
(i.e., any program can do anything it wants, as
the CPU’s protection mechanisms are disabled)
• But software can enter ‘protected mode’ (on a
80286 or higher) using a special instruction to
modify a bit within a processor control-register
• Once in protected mode, the segment-sizes can
be adjusted, accesses to physical memory (or to
peripheral devices) can be restricted, and tasks
can be isolated from interfering with one another
Enabling Protection
15 14 13 12
11 10
9
8
7
6
5
4
3
2
1
0
N E T E M P
E T S M P E
80286 Machine Status Word
Code-fragment that
enables protection
SMSW AX
OR AX, #1
LMSW AX
PE (Protection Enable) 0=no, 1=yes
Protected-Mode Segments
• Segments can have varying lengths
• Segments may or may not overlap
• Segments are assigned ‘access-attributes’
operating system
stack
data
code
GS
SS
DS
CS
Our ‘bare machine’
• If we want to do a “hands on” study of our
CPU, without any operating system getting
in our way, we have to begin by exploring
‘Real Mode’ (it’s the CPU’s startup state)
• We will need to devise a mechanism by
which our programs can get loaded into
memory (since we won’t have an OS)
• This means we must write a ‘boot loader’
What’s a ‘boot loader’
• A ‘boot loader’ is a small program that is
resident in the starting sector of a disk (or
tape or other non-volatile storage medium)
• After testing and initializing the machine’s
essential hardware devices, the startup
program in the ROM-BIOS firmware will
read the ‘boot loader’ into memory, at an
assigned location, and then jump there
PC ROM-BIOS BOOT_LOCN
Vendor’s Firmware
ROM-BIOS
No installed memory
Video Display Memory
Volatile Program Memory
VRAM
RAM
0x00007E00
0x00007C00
BOOT_LOCN 512 bytes
IVT and BDA
8086 memory-map
1-MB
Some Requirements
• A ‘boot loader’ has to be 512 bytes in size
(because it has to fit within a disk sector)
• Must begin with executable machine-code
• Must end with a special ‘boot signature’
• Depending on the type of storage medium,
it may need to share its limited space with
certain other data-structures (such as the
‘partition table’ on a hard disk, or the Bios
Parameter Block’ on a MS-DOS diskette)
Writing a ‘boot loader’
• Not practical to use a high-level language
• We need to use 8086 assembly language
(our classroom system provides ‘as86’)
• This assembler’s syntax is similar to the
standard set by Intel and Microsoft, but it
differs from the AT&T-style syntax that is
used with the Linux ‘as’ assembler
• Syntax is documented online: $ man as86
Using ROM-BIOS functions
• Our system firmware provides many basic
service-functions that real mode programs
can invoke (this includes boot-loaders):
– Video display functions
– Keyboard input functions
– Disk access functions
– System query functions
– A machine ‘re-boot’ function
Example: Write_String function
• Setup parameters in designated registers
– AH = function ID-number (e.g. 0x13)
– AL = cursor handling method (e.g. 0x01)
– BH = display page-number (e.g., 0x00)
– BL = color attributes (e.g., 0x0A)
– CX = length of the character-string
– DH, DL = row-number, column-number
– ES:BP = string’s starting-address (seg:off)
• Call BIOS via software interrupt (int-0x10)
Compiling and Installing
• Compiling our ‘boot loader’ using as86 is a
one-step operation:
$ as86 bootload.s –b bootload.b
• Installing our bootloader into the starting
sector of a floppy diskette is also simple:
$ dd if=bootload.b of=/dev/fd0
Executing a ‘boot-loader’
• Perform a system reset (CTRL-ALT-DEL)
• Our classroom machines will load GRUB
(the Linux GRand Unified Boot-loader)
• GRUB will display a menu of Boot Options
• You can choose to boot from floppy disk
• Another option: boot from a diskette-image
In-Class Exercises
• Go to our class website:
http://nexus.cs.usfca.edu/~cruse/cs630
• Download, assemble, and install our demo
‘bootmsw.s’
• Reboot machine and use GRUB’s menu to
boot our demo from the floppy diskette
• Modify our demo so it will ‘reboot’ (instead
of freeze) when a user presses any key
Programming Details
• It’s easy to include ‘await keypress’:
mov ah,# 0
; function-ID
int 0x16
; BIOS keyboard service
• It’s easy to include ‘reboot system’:
int 0x19
; BIOS reboot service
A valuable Online Reference
• Professor Ralf Brown’s Interrupt List
(see webpage link under ‘Resources’)
• It tells how to make BIOS system-calls, to
perform numerous low-level services from
within Real-Mode 8086 applications (such
as ‘boot loader’ programs)
Download