CE302 MICROPROCESSORS LECTURE I Levent Eren Outline • • • • Basic microprocessor and system architecture Memory Programming model Memory addressing – real mode – protected mode • Differences between C and ASM Levent Eren Microprocessor Architecture Basic Components • CPU Registers – special memory locations constructed from flip-flops and implemented on-chip – e.g., accumulator, count register, flag register • Arithmetic and Logic Unit (ALU) – ALU is where most of the action takes place inside the CPU • Bus Interface Unit (BIU) – responsible for controlling the address and data busses when accessing main memory and data in the cache • Control Unit and Instruction Set – CPU has a fixed set of instructions with which to work, e.g., MOV, CMP, JMP, ADD Levent Eren Microprocessor Architecture Instruction processing • • Processing of an instruction by a microprocessor consists of three basic steps (1) fetch instruction from the memory, (2) decode the instruction, and (3) execute (usually involves accessing the memory for getting operands and storing results) Operation of an early processor, e.g., 8085 Fetch 1 Busy Levent Eren Decode 1 Idle Execute Fetch 1 2 Busy Busy Decode 2 Idle Execute 2 …... Microprocessor Busy …... Bus Microprocessor Architecture Instruction processing • Modern microprocessors can process several instructions simultaneously at various stages of execution – this ability is called pipelining • Operation of the pipelined microprocessor, e.g., 80486 Fetch 1 Fetch 2 Decode 1 Fetch 3 Fetch 4 Decode 2 Decode 3 Execute 1 Execute Execute 2 3 Generate Address 1 Levent Eren Store 1 Decode 4 Fetch 5 Idle Execute 4 Fetch 6 Read 2 Decode 5 Decode 6 Idle Generate Address 2 Execute 5 Fetch 7 Bus Unit Idle Instruction Unit Execute 6 Execution Unit Address Unit System Architecture A19 Address Bus provides a memory address to the system memory and I/O address to the system I/O devices Data Bus transfers data between the microprocessor and the memory and I/O attached to the system Control Bus provides control signals that cause the memory or I/O to perform a read or write operation Levent Eren Address Bus A0 8086 System Data Bus (16 bit) D15 D0 Control Bus RD/WR Memory I/O To memory and I/O Processor Data and Address Bus Sizes Examples Processor Data Bus Address Bus Max Addressable Memory 8088 8 20 1,048,576 (1Mb) 8086 16 20 1,048,576 (1Mb) 80286 16 24 16,777,21 (16Mb) 80386dx 32 32 4,294,976,296 (4Gb) 80486 32 32 4,294,976,296 (4Gb) 80586/Pentium (Pro) 64 32 4,294,976,296 (4Gb) Levent Eren Memory • Microprocessor addresses a maximum of 2n different memory locations, where n is a number of bits on the address bus • Logical Memory – 80x86 supports byte addressable memory – byte (8 bits) is a basic memory unit – e.g., when you specify address 24 in memory, you get the entire eight bits, nothing less, nothing more – when the microprocessors address a 16-bit word of memory, two consecutive bytes are accessed Levent Eren Memory (cont.) • Physical Memory – The physical memories of 80x86 family differ in width • e.g., 8088 memory is 8 bits wide, • 8086, 80286 memory is 16 bits wide, and • 80386dx, 80486 memory is 32 bits wide – for programming there is no difference in memory width, because the logical memory is always 8-bit wide – memory is organized in memory banks • a memory bank is an 8-bit wide section of the memory • e.g., the 16-bit microprocessors contain two memory banks to form a 16-bit wide section of memory that is addressed as bytes or words Levent Eren Physical Memory System Example (16 bit microprocessor) High Bank (odd bank) Low Bank (even bank) FFFFFF FFFFFE FFFFFD FFFFFC FFFFFB FFFFFA 8 bits 8 bits 000005 000004 000003 000002 000001 000000 D15 - D8 Levent Eren D7- D0 Accessing Data in Memory Example (16 bit microprocessor) • • Accessing word from an even address - L.O. byte from the address specified and the H.O. byte from the next consecutive address What if you access a word on an odd address? • Example: access memory on address 125, i.e., we want to access data on address 125 (L.O.) and 126 (H.O.) – this requires two memory operations • read byte on address 125 • read byte on address 126 • swap the positions of these bytes internally since both entered the CPU on the wrong half of the data bus – 80x86 CPUs recognize this and perform transfer automatically • Your programs can access words at any address and the CPU will properly access and swap the data in memory Think about the speed of your program when accessing words at odd addresses • Levent Eren Memory Data Types • Numbers – – – – – – • bit (e.g.: 1) ; nibble = 4 bits DB:byte = octet = 8 bits DW:Word = 2 bytes = 16 bits (80x86 terminology) DD:DoubleWord = 4 bytes = 32 bits (80x86 terminology) Intel uses little Indian format (i.e., LSB at lower address) Signed Integers (2's complement) Text – – – – Levent Eren Letters and characters (7-bit ASCII standard), e.g., 'A'=65=0x41 Extended ASCII (8-bit) allows for extra 128 graphics/symbols) Collection of characters = Strings Collection of Strings = Documents Memory Data Types (cont.) • Programs – Commands (MOV, JMP, AND, OR, NOT) – Collections of commands = subroutines – Collection of subroutines = programs • • • • Floating point numbers (covered later) Images (GIF, TIF, JPG, BMP) Video (MPEG, QuickTime, AVI) Audio (voice, music) Levent Eren Example of Memory with Stored Data Levent Eren Address 0xFFFFF ... 0x75000 ... 0x70009 0x70008 0x70007 0x70006 0x70004 0x70003 0x70002 ... 0x60511 0x60510 0x6050F 0x6050E 0x6050D 0x6050C ... 0x55504 0x55003 0x55002 0x55001 ... 0x00000 Data (8-bits) Interpretation 0x55 byte '$’ '1' ‘9’ ‘2’ ‘E’ ‘C’ ‘E’ String 0x12 0x34 0x12 0x34 0x12 0x34 Word 0xFE opcode 0x02 opcode JE-2 Word 3x1 integer array of 16-bit words Word ADD AL,2 Program Programming Model Registers Note: 32 bit registers are not available on 8086, 8088, 80286 Levent Eren Programming Model Registers (examples) • General-Purpose Registers – AX(accumulator) often holds the temporary result after an arithmetic and logic operation – BX (base) often holds the base (offset) address of data located in the memory • Pointer and Index Registers – SP (stack pointer) used to address data in a LIFO (last-in, first-out) stack memory – BP (base pointer) often used to address an array of data in the stack memory Levent Eren Programming Model Flag Register • • • Flags indicate the condition of the microprocessor as well as its operation The flag bits change after many arithmetic and logic instructions execute Example flags, – C(carry) indicates carry after addition or a borrow after subtraction – O(overflow) is a condition that occurs when signed numbers are added or subtracted – Z(zero) indicates that the result of an arithmetic or logic operation is zero – T(trap) when the trap flag is set , it enables trapping through the onchip debugging feature Levent Eren Programming Model Segment Registers • • • • • • Segment registers generate memory addresses along with other registers in the microprocessor CS(code) defines the starting address of the section of memoryholding code(programs and procedures used by programs) DS(data) a section of memory that contains most data used by a program ES(extra) an additional data segment SS(stack) defines the area of memory used for the stack FS and GS available on 80386 and 80486 allow two additional memory segments for access by programs Levent Eren Real Mode Memory Addressing • • • • • 80286 - 80486 microprocessors operate in either the real or protected mode 8086, 8088, and 80186 only operate in the real mode Real mode operation allows the microprocessor to only address the first 1M byte of memory space (even if it is an 80486 microprocessor) Each of 80x86 processors operates in the real mode by default All real mode memory addresses consist of a segment address plus an offset address – the segment address (in one of the segment registers) defines the beginning address of any 64K byte memory segment – the offset address selects a location within the 64K byte memory segment Levent Eren Real Mode Memory Addressing (cont.) • • • Generation of 20-bit linear address from a segment:offset address in the real mode, each segment register (16 bits) is internally appended with a 0h on its rightmost end (i.e., the segment is shifted left by 4 bits) The segment and the offset are then added to form 20-bit memory address. Levent Eren Real Mode Memory Addressing Examples • (1) Linear address for Segment:Offset = 2222:3333 = 25553 Segment: offset address for Linear address=25553: • • Many Answers - One possibility: 2222:3333 Many Answers - One possibility: 2000:5553 • (2) Linear address for Segment:Offset = 1200:F445 = 21445 Segment: offset address for Linear address=21445: • • Levent Eren Many Answers - One possibility: 1200:F445 Many Answers - One possibility 2000:1445 Protected Mode Memory Addressing • In 80286 and later processors the addressing capabilities of a microprocessor are extended by changing the function the CPU uses to convert a logical address to the linear address space – the protected mode processors use a look up table to compute the physical address – the segment value is used as an index into an array (segment descriptor table) – the contents of the selected array element provides the starting address for the segment – the CPU adds this value to the offset to obtain the physical address Levent Eren Use of Segments Levent Eren Peripherals • Memory-mapped devices (special memory locations in the normal address space of the CPU) – BIOS: 0xF0000-0xFFFFF (bootstrap, I/O calls) – Video: 0xA0000-0xBFFFF and vBIOS: 0xC0000-0xC7FFF • I/O mapped devices (sound card, com ports, parallel port) – I/O addresses different than Memory addresses – Address Range: 0x0000 - 0xFFFF (16-bit) • Interrupts – Notifies the CPU when an event has occurred • Timer [update clock] , serial I/O [input data], Parallel I/O [ready] • Network adapter [packet arrived] Levent Eren C versus ASM x86 assembly C Null EQU 0 #define null 0 myseg SEGMENT PUBLIC myvar DW 017fh myvar2 DW ? int myvar = 0x017f, myvar2; start: Start() { mov ax, cs mov ds, ax mov si, myvar mov myvar2, null call dosxit END start myseg ENDS Levent Eren _SI=myvar myvar2 = null; dosxit(); } Hints for MP0 Basic Instructions Operation (example) Function MOV AX, CSEG Move contents of Code segment register to the AX register. MOV DX, constant Load the register DX with a fixed value. INC AX Increment register AX. CALL procedure Call a procedure. A return address will go on the stack. CMP AL, constant Compare the register AL with a constant. Set Flags JE label If flags indicate that previous compare was equal, jump to the address of the address defined by label. Levent Eren Hints for MP0 Program Directives C ASM Description #define EQU Compile-time substitutions. main main Where the program begins. #include extrn: Define external routine. int x = 0x5 x db 05h Allocate memory for a variable and initialize it with a value. Levent Eren CE302 Microprocessors Lecture 2 Levent Eren Izmir University of Economics Outline • • • • Programming with registers Instruction components and format Addressing modes Sampling of addressing modes Levent Eren ce302 Programming Model Registers Note: 32 bit registers are not available on 8086, 8088, 80286 Levent Eren ce302 Programming with Registers General-Purpose Registers • AX(accumulator) often holds the temporary result after an arithmetic and logic operation (also addressed as EAX, AH, or AL) • BX (base) often holds the base (offset) address of data located in the memory (also addressed as EBX, BX, BL) • CX (count) contains the count for certain instructions such as shift count (CL) for shifts and a counter (CX or ECX) with the LOOP instruction (also addressed as ECX, CH, or CL) • DX (data) holds – the most significant part of the product after a 16- or 32-bit multiplication, – the most significant part of the dividend before a division, and – I/O port number for a variable I/O instruction (also addressed as EDX, DH, DL) Levent Eren ce302 Programming with Registers Pointer and Index Registers • SP (stack pointer) used to address data in a LIFO (last-in, firstout) stack memory, most often used when – the PUSH and POP instructions are executed – a subroutine is CALLed or RETurned within a program – Don’t ever mess with this directly • • • • BP (base pointer) often used to address an array of data in the stack memory SI (source index) used to address source data indirectly for use with the string instructions DI (destination index) normally used to address destination data indirectly for use with the string instructions IP (instruction pointer) always used to address the next instruction executed by the microprocessor Levent Eren ce302 Programming with Registers Flag Register • • • Flags indicate the condition of the microprocessor as well as its operation The flag bits change after many arithmetic and logic instructions execute Example flags, – C(carry) indicates carry after addition or a borrow after subtraction – O(overflow) is a condition that occurs when signed numbers are added or subtracted – Z(zero) indicates that the result of an arithmetic or logic operation is zero – T(trap) when the trap flag is set , it enables trapping through the onchip debugging feature Levent Eren ce302 Programming with Registers Segment Registers • • • • CS(code) defines the starting address of the section of memoryholding code(programs and procedures used by programs) DS(data) a section of memory that contains most data used by a program ES(extra) an additional data segment SS(stack) defines the area of memory used for the stack. – the location of the current entry point in the stack segment is determined by the stack pointer register. – the BP register addresses data within the stack segment • FS and GS available on 80386 and 80486 allow two additional memory segments for access by programs Levent Eren ce302 Machine Language • • • Machine language is the native binary code that the microprocessor understands and uses as the instructions that control its operation Interpretation of machine’s language allows debugging or modification at the machine language level Microprocessor requires an assembler program, which generates machine code – the machine language instructions are too complex to generate by hand • Machine language instructions for the 8086-80486, vary in length from 1 to as many as 13 bytes – there are over 20000 variations of machine language instructions Levent Eren ce302 Machine Language (cont.) • 16 -bit instruction mode – if the machine operates in the real mode the instructions for Intel family of microprocessors are 16 -bit instructions – this means that instructions use 16-bit offset address and 16-bit registers • In the protected mode the D bit in the descriptor (within a lookup table of descriptors) indicates how the 80386/80486 instructions access register and memory data in protected mode – D = 0, the 80386/80486 assumes 16 bit instructions – D = 1, the 80386/80486 assumes 32 bit instructions • the 32-bit instruction mode assumes all offset addresses are 32 bits as well as all registers Levent Eren ce302 Instruction Components and Format Opcode • s Mode Displacement Data Immediate value Instruction Components Levent Eren ce302 Addressing Modes • • • Register - transfers a byte or word from the source register or memory location to the destination register or memory location MOV BX, CX Immediate - transfers an immediate byte or word of data into the destination register or memory location MOV AX, 3456h Direct - moves a byte or word between a memory location and a register MOV AL, [1234h] (1234h is treated as a displacement within data segment) Levent Eren ce302 Addressing Modes(cont.) • • Register Indirect (base relative or indexed) - transfers a byte or word of data between a register and the memory location addressed by an index (DI or SI) or base register (BP or BX) MOV AX, [BX] Base Plus Index (base relative indexed) - transfers a byte or word of data between a register and the memory location addressed by a base register (BP or BX) plus index (DI or SI) register MOV DX, [BX + DI] Levent Eren ce302 Addressing Modes(cont.) • Register Relative - transfers a byte or word of data between a register and the memory location addressed by an index (DI or SI) or base register (BP or BX) plus displacement MOV AX, [BX + 1000h] • Base Relative Plus Index (base relative indexed) - transfers a byte or word of data between a register and the memory location addressed by a base register (BP or BX) plus an index register (DI or SI) MOV AX, [BX + SI + 100h] Levent Eren ce302 Instruction Components Instructions have four components that specify the operation to execute, and how to treat the associated data. D W MOD OPCODE Levent Eren ce302 REG R/M Instruction Components OPCODE • Opcode (one or two bytes) selects the operation (e.g., addition, subtraction, move) performed by the microprocessor D W D - direction of the data flow D = 0 data flow to R/M field from register field D = 1 data flow to the register field from R/M in the next byte of the instruction OPCODE W - data size W = 0 data size is a byte W = 1 data size is a word/double word Levent Eren ce302 Instruction Components MOD • MOD field specifies the addressing mode for the selected instruction and whether the displacement is present with the specified addressing mode MOD MOD • REG R/M 00 01 10 11 FUNCTION no displacement 8-bit sign-extended displacement 16-bit displacement R/M is a register (register addressing mode) If the MOD filed contains a 00, 01, or 10, the R/M field selects one of the data memory-addressing modes, e.g., – MOV – MOV Levent Eren AL, [DI] (no displacement) AL, [DI + 2] (8-bit displacement) ce302 Instruction Components REG & R/M in Register Assignment Register assignment for the REG and R/M fields Code W = 0 (Byte) W = 1(Word) W =1 (Double Word) 000 001 010 011 100 101 110 111 AL CL DL BL AH CH DH BH AX CX DX BX SP BP SI DI EAX ECX EDX EBX ESP EBP ESI EDI Levent Eren ce302 Register Assignment Example • Consider 2 byte instruction 8BECh in the machine language program (assuming 16-bit instruction mode) binary representation: 1000 1011 1110 1100, from this we have opcode: D=W 100010 1 => => MOD REG R/M 11 101 100 => => => MOV a word moves into the register specified in the REG field R/M field also indicates register indicates register BP indicates register SP consequently the instruction is: MOV BP, SP Levent Eren ce302 Use of R/M Filed in Determining Addressing Mode • • If the MOD field contains a 00, 01, or 10, the R/M field takes on a new meaning Code Function Examples: 1. if MOD = 00 and R/M = 101 the addressing mode is [DI] 2. if MOD = 01 or 10 and R/M = 101 the addressing mode is [DI + 33h] or LIST[DI + 22H], where 33h, LIST, 22h are arbitrary values for displacement Levent Eren ce302 000 001 010 011 100 101 110 111 DS:[BX+SI] DS:[BX+DI] SS:[BP+SI] SS:[BP+DI] DS:[SI] DS:[DI] SS:[BP] DS:[BX] Base plus Index Register indirect Example • Consider machine language instruction 8A15h binary representation is: 1000 1010 0001 0101 opcode: D 100010 1 => => W MOD REG R/M 0 00 010 101 => => => => the instruction is: MOV DL, [DI] Levent Eren ce302 MOV a word moves into the register specified in the REG field byte no displacement indicates register DL indicates addressing mode [DI] Direct Addressing Mode • Direct Addressing mode (for 16-bit instructions) occurs whenever memory data are referenced by only the displacement mode of addressing, e.g., MOV [1000h], DL moves the contents of DL into data segment memory location 1000h MOV NUMB, DL moves the contents of DL into symbolic data segment memory location NUMB OPCODE D W 1 0 0 0 1 0 0 0 Byte 1 Displacement-low 0 0 0 0 0 0 0 0 Byte 3 Levent Eren MOD REG R/M 0 0 0 1 0 1 1 0 Byte 2 Displacement-high 0 0 0 1 0 0 0 0 Byte 4 ce302 MOV [1000h], DL Whenever the instruction has only a displacement: MOD R/M is always 00 is always 110 Immediate Instruction • Consider an instruction: MOV word PTR[BX + 1000h], 1234h OPCODE W 1 1 0 0 0 1 1 1 Byte 1 Displacement-low 0 0 0 0 0 0 0 0 Byte 3 Data-low 0 0 1 1 0 1 0 0 Byte 5 Levent Eren MOD R/M Moves 1234h into the word-sized memory location addressed by the sum of 1000h, BX, and DS x 10h 1 0 0 0 0 1 1 1 Byte 2 Displacement-high 0 0 0 1 0 0 0 0 WORD PTR directive indicates to the assembler that the instruction uses a word-sized memory pointer (if the instruction moves a byte of immediate data, then BYTE PTR directive is used. Byte 4 Data-high 0 0 0 1 0 0 1 0 Byte 6 ce302 The above directive are only needed when it is not clear if the operation is a byte or a word, e.g., MOV [BX], AL clear a byte move MOV [BX], 1 not clear, can be byte-, word, or double word-sized move should be for instance MOV BYTE PTR [BX], 1 Segment MOV Instructions • • The contents of a segment register are moved by MOV, PUSH, POP Segment registers are selected by appropriate setting of register bits (REG field) Code 000 001 010 011 100 101 ES CS SS DS FS GS Note: MOV CS, ?? and POP CS are not allowed Levent Eren Example: MOV BX, CS Segment Register OPCODE 1 0 0 0 1 1 0 0 REG is 001 R/M is 011 MOD REG R/M 1 1 0 0 1 0 1 1 => selects CS => selects BX Note that the opcode for this instruction is different for the prior MOV instructions ce302 Sampling of Addressing Modes Levent Eren ce302 Sampling of Addressing Modes Levent Eren ce302 Sampling of Addressing Modes Levent Eren ce302 CE302 Micropocessors Lecture 3 Levent Eren Izmir University of Economics Outline • • • • • • Memory Examples Logic instructions Shifting instructions Arithmetic operations Overflow and carries Important flags setting Levent Eren CE302 Memory Access Example myvar1 DW 01234h myvar2 DW 01234 myvar3 DW ? myvar4 DW 01BCDh ; define word variable ; (value=1234h) ; define word variable ;(value=1234d = 4D2) ; define word variable ;(value uncertain) mov si,OFFSET myvar2 mov ax,[si] ; use SI as a pointer to myvar2 ; (equiv C code: SI=&myvar2 ) ; read memory at myvar2 (*(&myvar2)) ; (indirect reference) mov bx,OFFSET ce302msg ; BX is a pointer to a string ; (equiv C code: BX=&ce302msg) ce302msg DB ‘CE302 is great' dec BYTE PTR [bx+1] ; make that ‘E' a ‘D' !!!! start: mov ax,cs mov ds,ax ; set up data segment ; DS=CS mov si, 1 inc ce302msg[SI] ; any memory reference we make is assumed to reside in ;the DS segment mov ax,myvar2 ; AX <- myvar2 ; == mov ax,[offset myvar2] ; == mov ax,[2] Levent Eren CE302 ; Use SI as an index ; == inc [SI + offset ce302msg] ; == inc [SI + 8] ; == inc [9] Memory Access Example (cont.) ;Memory can be addressed using four registers: ; SI -> Assumes DS ; DI -> Assumes DS ; BX -> Assumes DS ; BP -> Assumes SS !!! (this is why it isn't frequently used) ; Examples: mov ax,[bx] ; ax <- word in memory pointed to by BX mov al,[bx] ; al <- byte in memory pointed to by BX mov ax,[si] ; ax <- word pointed to by SI mov ah,[si] ; ah <- byte pointed to by SI mov cx,[di] ; di <- word pointed to by DI mov ax,[bp] ; AX <- SS:[BP] STACK OPERATION!!!! ; Furthermore, a fixed 8-bit or 16-bit displacement from the index and base registers is allowed. mov ax,[23h] ; ax <- word in memory DS:0023 mov ah,[bx+5] ; ah <- byte in memory DS:(BX+5) mov ax,[bx+si+107] ; ax <- word at DS:(BX+SI+107) mov ax,[bx+di+47] ; ax <- word at DS:(BX+DI+47) ; REMEMBER: memory to memory moves are ILLEGAL!!! mov [bx],[si] ;ILLEGAL mov [di],[si] ;ILLEGAL (use movsw) ; Special case: stack operations! pop myvar ; myvar <- SS:[SP] ; In addition, BX+SI and BX+DI are allowed: mov ax,[bx+si] mov ch,[bx+di] Levent Eren CE302 Flag Register AC (Alignment check) (VM) Virtual mode (RF) Resume (NT) Nested task (IOPL) Input/output privilege level (O) Overflow (D) Direction (I) Interrupt (T) Trace (S) Sign (Z) Zero (A) Auxiliary Carry (P) Parity (C) Carry 8086, 8088, 80186 80286 Levent Eren 80386, 80486DX 80486SX CE302 Logic Instructions • Logic instructions operate on a bit-by-bit basis NOT: AND: OR: XOR: • Except for NOT, these instructions affect the flags as follows: – – – – – – • A =~A A &= B A |= B A ^= B clear the carry (C) clear the overflow (O) set the zero flag (Z) if the result is zero, or clear it otherwise copy the high order bit of the result into the sign flag (S) set the parity bit (P) according to the parity (number of 1s) in the result scramble the auxiliary carry flag (A) The NOT instruction does not affect any flag Levent Eren CE302 Logic Instructions (cont.) • TEST (non-destructive AND) - logically ANDs two operands and sets the flags but does not save the result – typically one would use this instruction to see if a bit contains one e.g., test al, 1 – sets the flags identically to the AND instruction • AND and OR instructions are often used to mask out data – a mask value is used to force certain bits to zero or one within some other value – a mask typically affects certain bits and leaves other bits unaffected • AND forces selected bits to zero AND cl, 0DFh • OR forces selected bits to one OR cl, 0DFh Levent Eren CE302 Shifting Instructions Levent Eren CE302 Shifting Instructions (cont.) • SHL/SAL (shift left/shift arithmetic left) – moves each bit of the operand one bit position to the left the number of times specified by the count operand – zeros fill vacated positions at the L.O. bit; the H.O. bit shifts into the carry flag – A quick way to multiply by two – Useful in packing data, e.g., consider two nibbles in AL and AH that we want to combine SHL OR AH, 4 AL, AH ;requires 80286 or later NOTE: There are two forms of shifts 1) immediate shift count (8086, 8088 allow an immediate shift of 1 only, e.g., SHL AX, 1) 2) CL register to hold the shift count (e.g., SHL AX, CL) Levent Eren CE302 Example ;multiply AX by decimal 10 (1010) SHL AX, 1 MOV BX, AX SHL AX, 2 ADD AX, BX (Same as AX times 2+8 – associate prop) ;AX times 2 ;AX times 8 ;10 x AX ;multiply AX by 18 (10010) SHL MOV SHL ADD Levent Eren AX, 1 BX, AX AX, 3 AX, BX ;AX times 2 ;AX times 16 ;18 x AX CE302 Shifting Instructions (cont.) • SHR (shift right) – shifts all the bits in the destination operand to the right one bit – zeros fill vacated positions at the H.O. bit – the L.O. bit shifts into the carry flag • • A quick way to divide by two (works for unsigned numbers) Useful for unpacking data, e.g., suppose you want to extract the two nibbles in the AL register, leaving the H.O. nibble in AH and the L.O. nibble in AL: MOV SHR AND Levent Eren AH, AL AH, 4 AL, 0Fh ;get a copy of the H.O. nibble ;move H.O. to L.O. and clear H.O. ;remove H.O. nibble from AL CE302 Shifting Instructions (cont.) • SAR (shift arithmetic right) – shifts all the bits in the destination operand to the right one bit replicating the H.O. bit – the L.O. bit shifts into the carry flag – Main purpose is to perform a signed division by some power of two MOV AX, -15 SAR AX, 1 ; Result is -8 • In 80286 and later you can use SAR to sign extend one register into another, e.g., MOV SAR Levent Eren AH, AL AH, 8 If then CE302 AL contains 11110001 AH will contain sign bits extension 11111111 11110001 Shifting Instructions (cont.) • RCL (rotate through carry left) – rotates bits to the left, through the carry flag – bit in the carry flag is written back into bit zero (on the right) • ROL (rotate left) – rotates bits to the left – shifts operand’s H.O. bit into bit zero – e.g., extract bit 10 to 14 in AX and leave these bits in 0 to 4 ROL AX, 6 AND AX, 1Fh NOTE: There are two forms of rotate 1) use of immediate rotate count (8086, 8088 allow an immediate rotate of 1 only, e.g., ROL AX, 1) 2) use of register CL to hold the rotate count Levent Eren CE302 Shifting Instructions (cont.) • RCR (rotate through carry right) – rotates bits to the right, through the carry flag – bit in the carry flag is written back into H.O. bit (on the left) • ROR (rotate right) – rotates bits to rights – shifts operand’s L.O. bit into bit zero Levent Eren CE302 Shifting Operations Example mov ax,3 mov bx,5 ; Initial register values or ax,9 and ax,10101010b xor ax,0FFh neg ax not ax ; ; ; ; ; ax <- ax | 00001001 ax <- ax & 10101010 ax <- ax ^ 11111111 ax <- (-ax) ax <- (~ax) shl ax,1 shr ax,1 rol ax,1 ror ax,1 ; ; ; ; logical shift left by 1 bit logical shift right by 1 bit rotate left (LSB=MSB) rotate right (MSB=LSB) mov cl,3 shr ax,cl shl bx,cl ; Use CL to shift 3 bits ; Divide AX by 8 ; Multiply BX by 8 Levent Eren CE302 (bitwise OR) (bitwise AND) (bitwise XOR) (2's complement) (bitwise inversion) Simple Arithmetic Instructions • ADD (addition): A += B – Register addition, e.g., ADD AX, BX – Immediate addition, e.g., ADD DL, 33h – Memory to register addition, e.g., memory data added to AL: MOV DI, OFFSET NUMB ;address NUMB MOV AL, 0 ;clear sum ADD AL, [DI] ;add NUMB ADD AL, [DI + 1] ;add NUMB + 1 • NOTE: any ADD instruction modifies the contents of the sign, zero, carry, auxiliary carry, parity, and overflow flags Levent Eren CE302 Simple Arithmetic Instructions (cont.) • INC (increment addition): A++, e.g., memory data added to AL: MOV MOV ADD INC ADD DI, OFFSET NUMB AL, 0 AL, [DI] DI AL, [DI] ;address NUMB ;clear sum ;add NUMB ;add NUMB + 1 NOTE: The increment instructions do not affect the carry flag bit. Levent Eren CE302 Simple Arithmetic Instructions (cont.) • ADC (addition with carry) - functions as regular addition, except the bit in the carry flag (C) is also added to the result – used mainly to add numbers that are wider than 16 bits (8086 80286) or wider than 32 bits in the 80386, 80486) • Example: – addition of two 32-bit numbers (BX:AX) + (DX:CX): ADD AX, CX ADC BX, DX Levent Eren CE302 Simple Arithmetic Instructions (cont.) • SUB (subtraction): A -= B – Register subtraction, e.g., SUB CL, BL – Immediate subtraction, e.g., MOV CH, 22h Result is -34 (1101 1110) Flags change: SUB CH, 44h Z = 0 (result not zero) C = 1 (borrow) A = 1 (half-borrow) S = 1 (result negative) P = 1 (even parity) 0 = 0 (no overflow) • NOTE: any SUB instruction modifies the contents of the sign, zero, carry, auxiliary carry, parity, and overflow flags Levent Eren CE302 Simple Arithmetic Instructions (cont.) • DEC (decrement subtraction): A--, subtracts a 1 from a register or the contents of a memory location e.g., DEC BH NOTE: The increment instructions do not affect the carry flag bit. • SBB (subtract with borrow) functions as regular subtraction, except the carry flag (C), which holds the borrow, also subtracts from the difference – used mainly to subtract numbers that are wider than 16 bits (8086 80286) or wider than 32 bits in the 80386, 80486) • Example: – subtraction of two 32-bit numbers (BX:AX) - (SI:DI): SUB AX, DI SBB BX, SI Levent Eren CE302 Overflow and Carries • Carry – indicates a carry after addition or a borrow after subtraction – CF: carry flag (unsigned) {1 = CY (there is carry); 0 = NC (no carry)} – e.g., 36,864 (9000h) + 36,864 (9000h) = 73,728 (12000h) > 65,535 (FFFFh) {OV, CY} – carry is set when unsigned goes out of range (denotes an unsigned arithmetic overflow) • Overflow – condition that occurs when signed numbers are added or subtracted – OF: overflow flag (signed) {1 = OV, 0 = NV} – e.g., 20,480 (5000h) + 20,480 (5000h) = 40,960 (A000h) > 32,767 (7FFFh) {OV, NC} – overflow is set when signed goes out of range (denotes a signed arithmetic overflow) – Example: FFFFh + FFFFh = FFFEh {(-1) + (-1)} = -2; NV, CY Levent Eren CE302 Overflows & Carries Example MOV AX, 19 ADD AX, 7 ; AX <- AX + 7 = 26 NEG AX ; AX <- -AX = -26 = 0FFE6h MOV AX,0FFFEh ADD AX,3 ; 65534 ; Unsigned ; MOV AX,0FFFEh ; -2 ; Signed ADD AX,3 ; ; CPU sets flags for both cases (signed and unsigned) MOV BX,6 SUB BX,7 INC BX Levent Eren CE302 Flag Settings FLAG Name Description ZF Zero 1:ZR:Zero 0:NZ: Non-zero 1 indicates that the result was zero CF Carry 1:CY 0:NC Unsigned Math and shifting Needed a carry or borrow OF Overflow 1:OV 0:NV Signed Math Also (+) or (-) to be represented as a valid two’s complement number SF Sign Flag 1:NG: 0:PL: + MSB of result Levent Eren CE302 Notes CE302 MICROPROCESSORS Levent EREN Izmir University of Economics Outline • • • Unconditional jump Conditional branching Construction of loops CE302 Unconditional Jump JMP • Short jump 2-byte instruction that allows jumps or branches to memory locations within +127 and -128 bytes from the memory location following the jump OPCODE DISP JMP SHORT Label • Near jump 3-byte instruction that allows jumps or branches within +/32Kb from the instruction in the current code segment OPCODE DISP low JMP Label • Far jump 5-byte instruction that allows a jump to any memory location with in the entire memory space JMP Label • DISP high OPCODE IP low IP high CS low CS high For 80386, 80486, the near jump is within +/-2G if the machine operates in the protected mode and +/-32K bytes if operates in the real mode CE302 Conditional Branching • • • Logic and arithmetic instructions set flags Flags provide state information from previous instruction(s) Using flags we can perform conditional jumping, i.e., transfer program execution to some different place within the program if condition was true – jump back or forward in your code to the location specified – instruction pointer (IP) gets updated (to point to the instruction to which execution will jump) if condition was false – continue execution at the following instruction – IP gets incremented as usual CE302 Conditional Branching (cont.) • Conditional jumps are always short jumps in the 8086-80286 – the range of the jump is +127 bytes and -128 bytes from the location following the conditional jump • • • In 80386, 80486 conditional jumps are either short or near jumps Conditional jumps test: sign (S), zero (Z), carry (C), parity (P), and overflow (O) Note: an FFh is above the 00h in the set of unsigned numbers an FFh (-1) is less than 00h for signed numbers when you compare unsigned FFh is above 00h, but signed FFh is less than 00h CE302 Numerical Comparison • CMP(comparison) compares A to B – a subtraction that only changes the flag bits – useful for checking the entire contents of a register or a memory location against another value – usually followed by a conditional jump instruction CMP AL, 10h ;compare with 10h (contents of AL does not change) JAE SUBER ;if 10h or above then jump to memory location SUBER • SUB (subtraction) calculates difference A - B – saves results to A and set flags CE302 Numerical Comparison Condition Code Settings CMP Unsigned Operands Oprnd1, Oprnd2 Signed operands Z: equality/inequality Z: equality/inequality C: Oprnd1 < Oprnd2 (C=1) Oprnd1 >= Oprnd2 (C=0) C: no meaning S: no meaning O: no meaning S and O taken together If ((S=0) and (O=1)) or ((S=1) and (O=0)) then Oprnd1 < Oprnd2 If ((S=0) and (O=0)) or ((S=1) and (O=1)) then Oprnd1 >= Oprnd2 CE302 Comparing Signed Integers • Consider CMP AX,BX computed by the CPU – The Sign bit (S) will be set if the result of AX-BX has a 1 at the most significant bit of the result (i.e., 15th bit for 16-bit op) – The Overflow flag (O) will be set if the result of AX-BX produced a number that was out of range (-32768 - 32767 for 16-bit numbers) to be represented by an integer. • Difference in JS (jump on sign) and JL (jump less than) – The conditional jump JS looks at the sign bit (S) of the last compare (or subtraction). If S = = 1 then jump. – The conditional jump JL looks (S XOR O) of the last compare (or subtraction) • REGARDLESS of the value AX-BX, i.e., even if AX-BX causes overflow, the JL will be correctly executed CE302 Comparing Signed Integers (cont.) • • • JL is true if the condition: S xor O is met JL is true for two conditions: S=1, O=0: – (AX-BX) was negative and (AX-BX) did not overflow – Example (8-bit): (-5) - (2) = (-7) Result (-7) has the sign bit set Thus (-5) is less than (2). CE302 Comparing Signed Integers (cont.) • S=0, O=1: – Overflow!, Sign bit of the result is wrong! – Consider the following case: – – – – AX is a large negative number (-) BX is a positive number (+). The subtraction of (-) and (+) is the same as the addition of (-) and (-) The result causes negative overflow, and thus cannot be represented as a signed integer correctly (O=1). The result of AX-BX appears positive (S=0). Example (8-bit): (-128) - (1) = (+127) Result (+127) overflowed. Answer should have been (-129). Result appears positive, but overflow occurred Thus (-128) is less than (1), i.e., the condition is TRUE for executing JL CE302 Comparing Signed Integers CMP AX, BX BX AX AX – BX = 2 – (-4) = 2 + 4 = 6 =0110 So s = 0, no overflow (o = 0) -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 BX Therefore AX >= BX AX AX – BX = 6 – (-3) = 6 + 3 = 9 = 1001 So s = 1, overflow (o = 1) -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 AX Therefore AX >= BX BX AX – BX = 2 – 4 = -2 = 1110 So s = 1, no overflow (o = 0) -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 CE302 Therefore AX < BX Conditional Branching (cont.) • Terminology used to differentiate between jump instructions that use the carry flag and the overflow flag – Above/Below – Greater/Less • unsigned compare signed (+/-) compare Names of jump instructions J => Jump N => Not A/B G/L => Above/Below Greater/Less E => Equal CE302 Summary of Conditional Jump Instructions Command Description Condition JA=JNBE Jump if above Jump if not below or equal C=0 & Z=0 JBE=JNA Jump if below or equal C=1 | Z=1 JAE=JNB=JNC Jump if above or equal Jump if not below Jump if no carry C=0 JB=JNAE=JC Jump if below Jump if carry C=1 JE=JZ Jump if equal Jump if Zero Z=1 JNE=JNZ Jump if not equal Jump if not zero Z=0 JS Jump Sign (MSB=1) S=1 CE302 Summary of Conditional Jump Instructions Command Description Condition JNS Jump Not Sign (MSB=0) S=0 JO Jump if overflow set O=1 JNO Jump if no overflow O=0 JG=JNLE Jump if greater Jump if not less or equal S=O & Z=0 JGE=JNL Jump if greater or equal Jump if not less S=O JL=JNGE Jump if less Jump if not greater or equal S^O JLE=JNG Jump if less or equal Jump if not greater S^O | Z=1 JCXZ Jump if register CX=zero CX=0 CE302 Mapping High Level Branches into Linear Code true_label: …. done_label: CMP AX, BX JA true_label …. <False Processing> …. JMP done_label …. <True processing> <resume execution> CE302 Mapping High Level Branches into Linear Code (cont.) CE302 Mapping High Level Branches into Linear Code (cont.) • LOOP instruction – combination of a decrement CX and a conditional jump – LOOP decrements CX (ECX if in 32-bit mode) and if CX 0 it jumps to the address indicated by the label – if CX becomes a 0, the next sequential instruction executes ADDS PROC MOV MOV MOV NEAR CX, 100 SI, OFFSET BLOCK1 DI, OFFSET BLOCK2 ; load count Again: ADDS LODSW ADD STOSW LOOP RET ENDP AX, ES:[DI] Again CE302 ;get Block1 data; AX = [SI]; SI = SI + 2 ;add Block2 data ;store in Block2; [DI] = AX; DI = DI + 2 ;repeat 100 times Examples ; ; ; ; if (J <= K) then L := L + 1 else L := L - 1 J, K, L are signed words ; ; ; ; ; while (J >= K) do begin J := J - 1; K := K + 1; L := J * K; end; WhlLoop: MOV CMP JNEL INC JMP AX, J AX, K DoElse L ifDone DEC L MOV CMP JNGE DEC INC MOV IMUL MOV JMP DoElse: ifDone: QuitLoop: CE302 AX, J AX, K QuitLoop J K AX, J AX, K L, AX WhlLoop Example (LOOPNE) • The LOOPNE instruction is useful for controlling loops that stop on some condition or when the loop exceeds some number of iterations • Consider String1 that contains a sequence of characters that end with the byte containing zero • we want to convert those characters to upper case and copy them to String2 ….. String1 BYTE “This string contains lower case characters”, 0 String2 BYTE 128 dup (0) …….. CE302 Example (LOOPNE) LEA LEA MOV SI, String1 DI, String2 CX, 127 ;the same as use of OFFSET ;Max 127 chars to String2 StrLoop: LODSB CMP JB CMP JA AND AL, ‘a’ NotLower AL, ‘z’ NotLower AL, 5Fh NotLower: STOSB CMP AL, 0 LOOPNE StrLoop ;get char from String1; AL =[SI]; SI = SI + 1 ;see if lower case ;chars are unsigned ;convert lower -> upper case; ;bit 6 must be 0 ; [DI] = AL; DI = DI + 1 ;see if zero terminator ;quit if AL or CX = 0 CE302 Outline • • • Program organization Debugging hints MASM directives EENG4005 Program Organization • • • • Create block structure and/or pseudocode on paper to get a clear concept of program control flow and data structures Break the total program into logical procedures/macros Use jumps, loops, etc. where appropriate Use descriptive names for variables – noun_type for types – nouns for variables – verbs for procedures/functions EENG4005 Debugging Hints • • • Good program organization helps Programs do not work the first time Strategy to find problems – Use DEBUG breakpoints to check program progress – Use COMMENT to temporarily remove sections of code – "print" statements announce milestones in program • Test values/cases – Try forcing registers/variables to test output of a procedure – Use "print" statements to display critical data • • Double-check your own logic (Did you miss a special case?) Try a different algorithm, if all else fails... EENG4005 MASM Directives • General – TITLE • Includes • Definitions – – – – • DB DW DD EQU my_program.asm drive:\path\filename define byte (8bits) define word (16 bits) define doubleword (32 bits) names a constant Labels EENG4005 MASM Directives • Macros – Instead of using procedures, which require both stack and time resources, macros are fast and flexible – Advantages: • speed; no call instruction • readability - easier to understand program function – Drawbacks • space using the MACRO multiple times duplicates the code • tricky to debug (in particular when you have nested MACROs) • Procedures – “name” PROC NEAR/FAR – ENDP EENG4005 MASM Directives (cont.) • References to procedures – EXTERN “name” NEAR/FAR/BYTE/WORD – PUBLIC “ name” • Segment definition – SEGMENT “name” PUBLIC/STACK – ENDS • Segment register “Hooks” – ASSUME CS:CSEG; DES:CSEG; SS:STACK EENG4005 Example Program Structure TITLE ECE291:MPXXX COMMENT * In this MP you will develop program which take input from the keyboard………… * ;====== Constants ==================================================== ;ASCII values for common characters CR EQU 13 LF EQU 10 ESCKEY EQU 27 ;====== Externals ==================================================== ; -- LIB291 Routines extrn dspmsg:near, dspout:near, kbdin:near extrn rsave:near, rrest:near, binasc:near EENG4005 Example Program Structure (cont.) ; ==== LIBMPXXX Routines (Your code will replace calls to these functions) extrn LibKbdHandler:near extrn LibMouseHandler:near extrn LibDisplayResult:near extrn MPXXXXIT:near ;====== Stack ======================================================== stkseg segment stack ; *** STACK SEGMENT *** db 64 dup ('STACK ') ; 64*8 = 512 Bytes of Stack stkseg ends ;====== Begin Code/Data ============================================== cseg segment public 'CODE' ; *** CODE SEGMENT *** assume cs:cseg, ds:cseg, ss:stkseg, es:nothing EENG4005 Example Program Structure (cont.) ;====== Variables ==================================================== inputValid db 0 ; 0: InputBuffer is not ready ; 1: InputBuffer is ready ;-1: Esc key pressed operandsStr OutputBuffer db 'Operands: ','$' db 16 dup(?),'$' ; Contains formatted output ; (Should be terminated with '$') MAXBUFLENGTH InputBuffer EQU 24 db MAXBUFLENGTH dup(?),'$' ; Contains one line of user input include graphData.dat ; data PUBLIC OutputBuffer, inputValid, operandsStr PUBLIC graphData EENG4005 Example Program Structure (cont.) ;====== Procedures ==================================================== KbdHandler PROC NEAR <Your code here> KbdHandler ENDP MouseHandler PROC NEAR <Your code here> MouseHandler ENDP DisplayResult PROC NEAR <Your code here> DisplayResult ENDP EENG4005 Example Program Structure (cont.) ;====== Main Procedure ================================================ MAIN PROC FAR MOV MOV MOV MOV AX, CSEG ; Use common code and data segment DS, AX AX, 0B800h ; Use extra segment to access video screen ES, AX <here comes your main procedure> CALL MPXXXXIT MAIN ENDP CSEG ENDS END ; Exit to DOS MAIN EENG4005 Outline • • • • Multiplication Division Program Segment Prefix Command Line Parameters CE302 Multiplication • The product after a multiplication is always a double-width product, e.g, – – – – • if we multiply two 16-bit numbers , they generate a 32-bit product unsigned: (216 - 1) * (216 - 1) = (232 - 2 * 216 + 1 < (232 - 1) signed: (-215) * (-215) = 230 < (231 - 1) overflow cannot occur Modification of Flags – Most flags are undefined after multiplication – O and C flags clear to 0 if the result fit into half-size register – e.g., if the most significant 16 bits of the product are 0, both flags C and O clear to 0 CE302 Multiplication (cont.) • Two different instructions for multiplication – MUL – IMUL • • • Multiply unsigned Integer Multiply (2’s complement) Multiplication is performed on bytes, words, or double words Which operation to perform depends on the size of the multiplier The multiplier can be any register or any memory location MUL CX ; AX * CX (unsigned result in DX--AX); IMUL WORD PTR [SI] ; AX * [word contents of memory location ; addressed by SI] (signed product in DX--AX) CE302 Multiplication (16 bit) The use of the AX (and DX) registers is implied!!!!! Multiplicand Multiplier AX (16-bit register, 16-bit memory variable) DX, AX = PRODUCT (High word in DX : Low word in AX) CE302 Multiplication • 8-bit multiplication Multiplicand Multiplier AX • AL (8-bit register, 8-bit memory variable) PRODUCT 32-bit multiplication Multiplicand Multiplier EAX (32-bit register, 32-bit memory variable) EDX, EAX PRODUCT (High word in EDX : Low word in EAX) – 32-bit multiplication is available only on 80386 and above CE302 Binary Multiplication • Long Multiplication is done through shifts and additions 0 1 1 0 0 0 1 0 (98) x 0 0 1 0 0 1 0 1 (37) ------------------------01100010 01100010- 0 1 1 0 0 0 1 0 - - - - - (3626) • • This works if both numbers are positive To multiply a negative numbers, the CPU will store the sign bits of the numbers, make both numbers positive, compute the result, then negate the result if necessary CE302 Division • X / Y = Q; R X Dividend Y Divisor Q Quotient R Remainder Examples (Signed Integers) Note: Remainder has the same sign as X (Dividend) CE302 X/Y Q R 9/4 -9 / 4 9 / -4 -9 / -4 2 -2 -2 2 1 -1 1 -1 Division (cont.) • Two different instructions for division – DIV – IDIV • • • • Division unsigned Integer Division (2’s complement) Division is performed on bytes, words, or double words Which operation to perform depends on the size of the divisor The dividend is always a double-width dividend that is divided by the operand (divisor) The divisor can be any register or any memory location CE302 Division (32-bit/16-bit) The use of the AX (and DX) registers is implied!!!!! Dividend Divisor Quotient Remainder DX, AX (high word in DX, low word in AX) (16-bit register, 16-bit memory variable) AX DX CE302 Division (cont.) • 16-bit/8-bit Dividend Divisor Quotient Remainder AX (8-bit register, 8-bit memory variable) AL AH • 64-bit/32-bit • Dividend EDX, EAX (high double word in EDX, low double word in EAX) Divisor (32-bit register, 32-bit memory variable) Quotient EAX Remainder EDX Available on 80386 and above CE302 Division (cont.) • • Division of two equally sized words Prepare the dividend – Unsigned numbers: move zero into high order-word – Signed numbers: use signed extension (implicitly uses AL, AX, DX registers) to fill high-word with ones or zeros – CBW (convert byte to word) AX = xxxx xxxx snnn nnnn (before) AX = ssss ssss snnn nnnn (after) – CWD (convert word to double) DX:AX = xxxx xxxx xxxx xxxx snnn nnnn nnnn nnnn (before) DX:AX = ssss ssss ssss ssss snnn nnnn nnnn nnnn (after) – CWDE (convert double to double-word extended) - 80386 and above CE302 Division (cont.) • Flag settings – none of the flag bits change predictably for a division • A division can result in two types of errors – divide by zero – divide overflow (a small number divides into a large number), e.g., 3000 / 2 • AX = 3000; • Devisor is 2 => 8 bit division is performed • Quotient will be written to AL => but 1500 does not fit into AL • consequently we have divide overflow • in both cases microprocessor generates interrupt (interrupts are covered later in this course) CE302 Division (Example) Division of the byte contents of memory NUMB by the contents of NUMB1 Unsigned MOV MOV DIV MOV MOV AL, NUMB AH, 0 NUMB1 ANSQ, AL ANSR, AH Signed ;get NUMB ;zero extend ;save quotient ;save remainder CE302 MOV CBW IDIV MOV MOV AL, NUMB NUMB1 ANSQ, AL ANSR, AH ;get NUMB ;signed-extend ;save quotient ;save remainder Division (cont.) • What do we do with remainder after division? – use the remainder to round the result – drop the remainder to truncate the result – if the division is unsigned, rounding requires that remainder is compared with half the divisor to decide whether to round up the quotient – e.g., sequence of instructions that divide AX by BL and round the result DIV ADD CMP JB INC BL AH, AH AH, BL NEXT AL NEXT: CE302 ;double remainder ;test for rounding Program Segment Prefix (PSP) • When a program is loaded into memory for execution, DOS first builds up a program segment prefix immediately before the program is loaded into memory. • This PSP contains lots of information, some of it useful, most of it obsolete. • Understanding the layout of the PSP is essential for programmers designing assembly language programs. • The PSP is 256 bytes long CE302 Program Segment Prefix (PSP) Offset 0 2 4 5 0Ah 0Eh 12h 16h 2Ch 2Eh 50h 53h 5Ch 6Ch 80h 81h Length 2 2 1 5 4 4 4 22 2 34 3 9 16 20 1 127 Description An INT 20h instruction is stored here Program ending address Unused, reserved by DOS Call to DOS function dispatcher Address of program termination code Address of break handler routine Address of critical error handler routine Reserved for use by DOS Segment address of environment area Reserved by DOS INT 21h, RETF instructions Reserved by DOS Default FCB #1 Default FCB #2 Length of command line string Command line string CE302 PSP – Program Ending Address • Field number two contains a value which points to the last memory address allocated to your program. • By subtracting the address of the PSP from this value, you can determine the amount of memory allocated to your program CE302 PSP – Environment Area Address • This field contains the segment address of the environment storage area • The environment strings always begin from an offset of zero from the above segment address • This area of memory consists of a sequence of zeroterminated strings using the format: string1 0 string2 0 string3 0 0 • Strings are usually placed in the environment area using DOS commands like PATH or SET • Generally an environment string takes the form name = parameters CE302 PSP – Environment Area Address • For example the statement set ipath=c:\assembly\include copies the string “ipath=c:\assembly\include” into the environment string storage area. • Many programs scan the env storage area for paths and other information. Your programs can take advantage of this too. CE302 PSP – Command Line String • Many programs allow you to append parameters after the executable name: e.g. Notepad mydoc.txt • This command line string is stored in the PSP • Location 80h of the PSP stores the length of the CLS • Locations 81h through FFh contain the string itself • You can use CLS in your ASM programs just like you would use argc, argv to access command line parameters in C/C++ CE302 PSP – Command Line String • For example, consider MYPGM parameter1, parameter2 • The CLS for this will be 23, “ parameter1, parameter2”, 0Dh • Notice that the carriage return character is not figured into the length • Please read Section 13.3.12 of the online text for an in depth discussion of this topic with parsing examples CE302 Accessing the PSP • Although the PSP is loaded into memory immediately before your program, that doesn’t necessarily mean that it appears 100h bytes before your code • Your data segments may have been loaded into memory before your code segments, thereby invalidating this method of locating the PSP • The segment address of the PSP is passed to your program in the DS register • Use the following code to extract the PSP segment address CE302 Accessing the PSP Push ds ;Save PSP value in the stack Mov ax, seg DSEG ;Point DS and ES to our data segment Mov ds, ax Mov es, ax Pop PSP ;Store PSP segment address into “PSP variable CE302 Accessing the PSP • In DOS 5.0 and later, you can make a DOS call to obtain the PSP address • Load AH with 51h and execute an int 21h instruction • DOS will return the segment address of the current PSP in the bx register CE302 EENG 4005 Microprocessors Outline • • • • • Program Stack PUSH & POP instructions Procedures Macros Macros vs. procedures EENG4005 Stack Key Characteristics • • • Used to store temporary data during program execution One point of access - the top of the stack A stack is always operated as Last-In-First-Out (LIFO) storage, i.e., data are retrieved in the reverse order to which they were stored • Instructions that directly manipulate the stack – PUSH – POP - place element on top of stack remove element from top of stack EENG4005 Stack Implementation in Memory Original SP In Use In Use In Use Direction of increasing memory addresses In Use Stack grows in direction of decreasing memory addresses In Use In Use SS:SP FREE FREE FREE FREE EENG4005 SS Stack Implementation in Memory (cont.) • • SS - Stack Segment SP (stack pointer) always points to the top of the stack – SP initially points to top of the stack (high memory address). – SP decreases as data is PUSHed PUSH AX ==> SUB SP, 2 ; MOV [SS:SP], AX – SP increases as data is POPed POP AX ==> MOV AX, [SS:SP] ; ADD SP, 2 • BP (base pointer) can point to any element on the stack EENG4005 PUSH Instruction Example To address 12FFF Register Array AX BX 6A 03800 037FF B3 037FE PUSH BX 6AB3 6AB3 CX DX SP 0800 SS 0300 03000 STACK segment EENG4005 POP Instruction Example To address 0FFFF Register Array AX BX 392F POP BX 392F CX 39 01008 01007 2F 01006 DX SP 1006 SS 0000 00000 STACK segment EENG4005 PUSH & POP (More I) • • • PUSH and POP always store or retrieve words of data (never bytes) in the 8086-80286 microprocessor The 80386/80486 allow words or double words to be transferred to and from the stack The source of data for PUSH – any internal 16-bit/32-bit register, immediate data, any segment register, or any two bytes of memory data • The POP places data into – internal register, segment register (except CS), or a memory location EENG4005 PUSH & POP (More II) • The 80286 and later microprocessors there is also PUSHA and POPA to store and retrieve, respectively the contents of internal register set (AX, CX, DX, BX, SP, BP, SI, and DI) • Stack initialization, example: – assume that the stack segment resides in memory locations 10000h-1FFFFh – the stack segment (SS)is loaded with 1000h – the SP is loaded with 0000h - to start the stack at the top of the 64K…WHY? EENG4005 The Stack Use • To store – registers – return address information while procedures are executing – local variables that procedures may require • To pass parameters to procedures EENG4005 Temporary Register Storage • Push and Pop registers to preserve their value Example: PUSH AX PUSH BX ... < modify contents of Registers AX & BX > ... POP BX POP AX ; Place AX on the stack ; Place BX on the stack ; Restore original value of BX ; Restore original value of AX EENG4005 Store Return Address of a Procedure PrintRec PrintRec main main PROC NEAR ... <Print value of a record> ... RET ENDP PROC FAR ... <Calculate Scores> ... CALL PrintRec <Continue Execution HERE> ... CALL DOSXIT ENDP At execution time 1. processor encounters the CALL to the procedure 2. pushes the return address (instruction pointer of the next instruction after the CALL) onto the stack 3. jumps to PrintRec 4. executes the code therein 5. pops the return address off the stack 6. returns to the calling code EENG4005 Passing Parameters on the Stack • • • Stack can be used to pass parameter(s) to a procedure The caller pushes the procedure parameter onto the stack and the callee finds the parameter there When the procedure completes its task, the parameter should be popped from the stack MOV PUSH CALL AX, OFFSET String AX getStr ;the proc getStr expects the offset to the String to ;be on the stack EENG4005 Passing Parameters on the Stack Example ;Use of Procedures when parameters are passed using Stack ………. ;====== Stack ======================================================== stkseg segment stack ; *** STACK SEGMENT *** db 64 dup ('STACK ') ; 64*8 = 512 Bytes of Stack stkseg ends ;====== Begin Code/Data ============================================== cseg segment public 'CODE' ; *** CODE SEGMENT *** assume LEN CR LF Prompt1 Prompt2 String cs:cseg, ds:cseg, ss:stkseg, es:nothing EQU EQU EQU BYTE BYTE BYTE 80 0dh 0ah "Input a string", 0 "Do another? ", 0 (LEN +1) DUP (?) EENG4005 Passing Parameters on the Stack Example (cont.) Main PROC Begin: mov push call mov push call mov push call mov push call FAR ax, OFFSET Prompt1 ax putStr ax, OFFSET String ax getStr ax, OFFSET String ax putStr mov push call ax, OFFSET String ax getStr mov cmp je bx, OFFSET String BYTE PTR [bx], 'y' Begin mov int MAIN ENDP CSEG ENDS END ax, OFFSET Prompt2 ax putStr EENG4005 ax, 4c00h 21h MAIN Passing Parameters on the Stack Example (cont.) ;OFFSET of string to be printed must ;be on the stack and the string must ;be null terminated putStr PROC NEAR push bp mov bp, sp push ax push bx push dx mov bx, [bp + 4] ;expect bx to point to string mov ah, 2h ; prepare to print a char with 21h nextChar: cmp BYTE PTR [bx], 0h ;check for null terminator je foundEnd ;when found exit mov dl, [bx] ; print with 21h int 21h inc bx ;point to next char jmp nextChar foundEnd: pop dx OFFSET String pop bx RETURN IP pop ax BP pop bp OLD BP ret 2 AX putStr ENDP BX Removes passed parameters from the stack EENG4005 SP DX Passing Parameters on the Stack Example (cont.) ;OFFSET of large enough buffer must ;have been pushed onto stack ;string will be null terminated getStr PROC NEAR push bp mov bp, sp push ax push bx mov bx, [bp + 4] ;base address of storing buffer mov ah, 01h int cmp 21h al, CR getLoop: je mov getEnd [bx], al ;bx points to storage location inc bx jmp getLoop getEnd: mov BYTE PTR [bx], 0 ;CR is converted in null term pop pop pop ret getStr bx ax bp 2 ENDP OFFSET String RETURN IP BP OLD BP AX SP ;look for CR in al EENG4005 BX Procedures (Overview) • • • Group of instructions that usually perform one task Reusable section of the software that is stored in memory once, but use as often as necessary The stack stores the return address whenever a procedure is called during the execution of the program – CALL pushes the address of the instruction following it on the stack – RET removes an address from the stack so the program returns to the instruction following the call PROC NEAR My_Subroutine PROC FAR My_Subroutine RET • PUSH • JUMP • PUSH • PUSH • JUMP POP (CS:) IP IP Offset My_Subroutine Near calls and returns transfer control between procedures in the same code segment CS IP Segment My_Subroutine:Offset My_Subroutine Far calls and returns pass control between different segments EENG4005 Procedures (Overview cont.) • Procedures should save and restore registers that are modified in a subroutine. PrintRec PROC NEAR PUSH AX PUSH BX PUSH CX PUSH DX PUSH SI < Code modifies AX,BX,CX,DX,SI > POP SI POP DX POP CX LIB291 Routine to save ALL registers POP BX POP AX RSAVE: Save ALL registers RREST: Restore ALL registers RET PrintRec ENDP EENG4005 Procedures (Overview) • Parameters to a procedure can be passed in – – – – – on the stack global memory locations registers in the code stream in a parameter block reference by a pointer EENG4005 Passing Parameters in Registers • Example: putsi (put short integer) routine outputs the value in AL as a signed integer putsi putsi PROC PUSH AX CBW PUTI POP RET ENDP AX ;saves AH’s values ;sign extend AL --> AX ;do the work; puti expects the value of the ; signed integer in the AX register ;restore AH EENG4005 Passing Parameters in the Code Stream • Example: PrintLp: MyPrint BYTE “Code stream parameter.”, 0 Consider the following implementation of MyPrint MyPrint PROC NEAR PUSH BP MOVE BP, SP PUSH BX PUSH AX EndStr: MyPrint MOV MOV CMP JZ PUTC INC JMP INC MOV POP POP POP RET ENDP EENG4005 BX, 2[BP] AL, CS:[BX] AL, 0 EndStr BX PrintLp BX 2[BP], BX AX BX BP ;load return address into BX ;get next character ;check for end of the string ;move to the next char ;point at first byte beyond zero ;save as a new return address Passing Parameters via a Parameter Block Consider simple subroutine that adds J and K together, storing the result in I. ParmBlock WORD I I WORD ? ;I, J, K must appear in this order J WORD ? K WORD ? …… LES bx, ParmBlock CALL AddEm AddEm PROC NEAR PUSH AX MOV AX, ES:2[BX] ;get J’s value ADD AX, ES:4[BX] ;add in K’s value MOV ES:[BX], AX ;store result in I RET AddEM ENDP EENG4005 Macros • A macro inserts a block of statements at various points in a program during assembly • Text substitutions made at compile time – – – – NOT a procedure -- Code is literally dumped into program Parameter names are substituted Useful for tedious programming tasks Instantiated within code segment. EENG4005 Macros (cont.) • General Format MACRO_NAME MACRO Param1,Param2,...,ParamN LOCAL MyLabel Your Code ... ... Param1 ... ...Param2 ... Your Code ... JMP MyLabel Your Code ... MyLabel: ... ParamN ... Your Code ... ENDM EENG4005 Local Variable(s) in a Macro • • A local variable is one that appears in the macro, but is not available outside the macro We use the LOCAL directive for defining a local variable – If the label MyLabel in the previous example is not defined as local, the assembler will flag it with errors on the second and subsequent attempts to use the macro • • The LOCAL directive must always immediately follow the MACRO directive without any intervening comments or spaces Macros can be placed in a separate file – use INCLUDE directive to include the file with external macro definitions into a program – no EXTERN statement is needed to access the macro statements that have been included EENG4005 Macros (cont.) Example: DIV16 MACRO Result, X, Y ; Store into Result the signed result of X / Y ; Calculate Result = X / Y ; (all 16-bit signed integers) ; Destroys Registers AX,DX MOV AX, X CWD IDIV Y MOV Result, AX ENDM • EENG4005 ; Load AX with Dividend ; Extend Sign into DX ; Signed Division ; Store Quotient Macros (cont.) • Example: Using the macro in a program ; Variable Section varX1 DW 20 varX2 DW 4 varR DW ? ; Code Section DIV16 varR,varX1,varX2 Will Actually Generate the following code (You won't actually see this unless you debug the program). MOV AX, varX1 CWD IDIV varX2 MOV varR, AX EENG4005 Macros vs Procedures Proc_1 PROC MOV MOV MOV RET Proc_1 ENDP CALL …... CALL …... Macro_1 …… Macro_1 NEAR AX, 0 BX, AX CX, 5 Macro_1 MACRO MOV AX, 0 MOV BX, AX MOV CX, 5 ENDM EENG4005 Proc_1 Proc_1 Macros vs Procedures (cont.) • In the example the macro and procedure produce the same result • The procedure definition generates code when the assembler encounters the PROC directive • The macro does not emit any code when processing the statements between the MACRO and ENDM – Upon encountering Macro_1 in the mnemonic field, MASM assembles every statement between the MACRO and ENDM directives and emits that code to the output file – At run time, the processor executes these instructions without the call/ret overhead EENG4005 Macros vs Procedures (cont.) • Advantage of using macros – execution of MACRO expansion is usually faster (no call and ret) than the execution of the same code implemented with procedures • Disadvantage – assembler copies the macro code into the program at each macro invocation – if the number of macro invocations within the program is large then the program will be much larger than when using procedures EENG4005