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
© Copyright 2026 Paperzz