Download presentation
Presentation is loading. Please wait.
1
Principles of Microcomputer and Interface
By Dr. Qiang Huang
2
Contact information Lecturer: Dr. Q Huang Office: Room 1410 Science and Technology Building Office Hours: Monday-Friday 8:30am~05:30pm Tel: /
3
Course Information Textbook – The 80x86 IBM PC and Compatible Computers Volumes I & II, 4th Edition, Muhammad Ali Mazidi, Tsinghua University Lab – report by individual 4 Lab assignments Reference Books [1] 微型计算机技术及应用(第3版),戴梅萼等,清华大学出版社, 2003。 [2] 微机原理与接口技术,周明德,人民邮电出版社,2002.4 [3] 计算机硬件技术及应用基础,邹逢兴,国防科技大学出版社, 2001年。
4
Course Section Allocation
Chapter Content Session Allocation Notes Lecture Lab Discussion Exe Total 1 Microcomputer Overview 4 2 Assembly Programming 8 12 3 Buses and Memory 6 10 I/O Systems 5 Parallel I/O Serial I/O 7 Interrupts 14 DMA, A/D and D/A
5
Lab Section Allocation
Num Experiment Name Experiment Content Requirement Sessions Number of Students Type 1 Introduction to TDN86/88 System Get the student familiarized with the TDN86/88 system by developing a simple assembly program. compulsory 4 2 Verify RAM Extension Extending the system RAM with 6264 device. 3 8255A Parallel Port Programming 8255A parallel interface controller. Calculator Development Design a numeric calculator with user input and display. 6 Design
6
Grading Police Attendance and Homework Lab Final Exam —— 10.00%
—— 20.00% Final Exam ——70.00%
7
Guideline for Lab Report/Assignment Submission
Deadline for each assignment will be given with individual assignment. Deadline for lab reports are due on the same day of the following weeks after the lab section. Person to collect the report/assignment is to be appointed (should produce a list of students who has submitted) NO Delay Is Allowed!
8
Submission Record ID Name Signature 20060001 张三 (张三签名) 20060002 李四
(李四签名) 王五 (王五签名)
9
Course Description This course is a core course for computer science subject. It is the fundamental of computer technique. Microcomputer technology has been advanced very rapidly recently from 8086, 80186, 80286, to M-Core microprocessors. This course examines the architecture and instruction set of the INTEL 8086 and 8088 chips used on the IBM-PC. Topics include: machine execution; addressing; input/output; arithmetic; branching, and control instructions. Students use the IBM-PC macro assembler to code and debug typical applications. Knowledge of the 8086/88 Assembler language is further extended through the study of arithmetic and string operations, conversions from binary to ASCII, table handling routines and disk I/O. Further study of the INTEL 8086 family. Architecture and hardware structures for the 8086 microprocessor: bus structure, memories and I/O interfacing. In the laboratory emphasis is given to the design of complex applications by using of the PC based equipment. After studying this course the student will build up a strong knowledge of the microcomputer system software and hardware, which could prepare them for future course study.
10
Chapter 0 Introduction to computing
11
Data Representation Digital computers are binary in nature. They operate only on 0’s and 1’s Everything must be expressed in terms of 0’s & 1’s - Instructions, data, memory locations. 1 = “on” voltage at output of electronic device is high (saturated). 0 = “off” voltage at output of electronic device is zero.
12
Data Representation The smallest element of information is a “bit” – 0 or 1. But by itself a bit does not convey much information. Therefore: 8 bits in succession make a “byte”, the smallest addressable binary piece of information 2 bytes (16 bits in succession) make a “word” (machine dependent)
13
Data Representation 2 words (32 bits in succession) make a “double word”. We can easily understand base 10 numbers. So we need to learn how to convert between binary and decimal numbers. Decimal numbers are not useful to the computer: a compromise – base 16 numbers (hexadecimal) and base 8 nos., or “octal”.
14
Binary Numbers Each position in a binary number, starting from the right and going left, stands for the power of the number 2 (the base). The rightmost position represents 20, which = 1. The second position from the right represents 21= 2. The third position from the right represents 22 = 4. The fourth position from the right represents 23 = 8.
15
Hexadecimal Numbers Large binary numbers are cumbersome to read.
==> hexadecimal numbers are used to represent computer memory and instructions. Hexadecimal numbers range from 0 to 15 (total of sixteen). Octal numbers range from 0 to 7 (total of 8)
16
Hexadecimal Numbers The letters of the alphabet are used to the numbers represent 10 through 15. where A=10, B=11, C=12, D=13, E=14, and F=15 But why use hexadecimal numbers? 4 binary digits (half a byte) can have a maximum value of 15 (1111), and a minimum value of 0 (0000).
17
Hexadecimal Numbers If we can break up a byte into halves, the upper and lower halves, each half would have 4 bits. A single hexadecimal digit between 0 and F could more concisely represent the binary number represented by those half-bytes. A byte could then be represented by two hexadecimal digits, rather than 8 bits
18
Numbers A radix is placed after the number to indicate the base of the number. These are always in lower case. If binary, the radix is a “b”; if hexadecimal, “h”, if octal, “o” or “q”. Decimal is the default, so if it has no indication, it is assumed to be decimal. A “d” can also be used.
19
Signed and Unsigned Integers
Integers are typically represented by one byte (8 bits) or by one word (16 bits). There exist two types of binary integers: signed and unsigned
20
Unsigned Integers Unsigned integers are easy – they use all 8 or 16 bits in the byte or word to represent the number. If a byte, the total range is 0 to 255 ( to ). If a word, the total range is 0 to 65,535 ( to ).
21
Signed Integers Are slightly more complicated, as they can only use 7 or 15 of the bits to represent the number. The highest bit is used to indicate the sign. A high bit of 0 positive number A high bit of 1 negative number - counter intuitive, but more efficient.
22
Signed numbers (cont.) The range of a signed integer in a byte is therefore, -128 to127, remembering that the high bit does not count. The range of a signed integer in a word is –32,768 to 32,767.
23
The One’s Complement The one’s complement of a binary number is when all digits are reversed in value. For example, has a one’s complement of
24
Storage of Numbers Unsigned numbers and positive signed numbers are stored as described above. Negatively signed numbers, however, are stored in a format called the “Two’s complement” which allows it to be added to another number as if it was positive.
25
Storage of Numbers (cont.)
The Two’s Complement of a number is obtained by adding 1 to the lowest bit of the one’s complement of the number. The Two’s Complement is perfectly reversible TC (TC (number)) = number.
26
Storage of Numbers (cont.)
Therefore, if the high bit is set (to 1), the number is a negatively signed integer. But, its decimal value can only be obtained by taking the two’s complement, and then converting to decimal. If the high bit is not set (= 0), then the number can be directly converted into decimal.
27
Example 0 0 0 0 1 0 1 0 is a positive number, as the high bit is 0.
can be easily converted to 10 decimal in a straightforward fashion. = 10 decimal
28
Example (cont.) is a negative number because of the high bit being set. , however, is not –10, as we first have to determine its two’s complement.
29
Example (cont.) One’s Complement of ( ) ( ), add 1 ( ) = -118
30
Character Representation – ASCII
How do we represent non-numeric characters as well as the symbols for the decimal digits themselves if we want to get an alphanumeric combination? Typically, characters are represented using only one byte minus the high bit (7-bit code).
32
Character Representation – ASCII (cont.)
Bits 00h to 7Fh represent the possible values. The ASCII table maps the binary number designated to be a character with a specific character. If the eighth bit is used (as is done in the IBM PC to extend the mapping to Greek and graphics symbols), then the hex numbers used are 80h to FFh.
33
Character Representation – ASCII (cont.)
The programmer has to keep track of what a binary number in a program stands for. It is not inherent in the hardware or the operating system. High level languages do this by forcing you to declare a variable as being of a certain type. Different data types have different lengths
34
Chapter 1 The 80x86 Microprocessor
35
Some History Date Event Comments 1947 1st transistor Bell Labs 1958
1st IC Jack Kilby (MSEE Winner of 2000 Nobel prize 1971 1st microprocessor Intel (calculator market) 1974 Intel 4004 2300 transistors 1978 Intel 8086 29K transistors 1989 Intel 80486 1M transistors 1995 Intel Pentium Pro 5.5M transistors 2006 Intel Montecito 1.7B transistors
36
Von Neumann system A typical Von Neumann system has three major components: the central processing unit (or CPU), memory, and input/output (or I/O). The way a system designer combines these components impacts system performance: In VNA machines, like the 80x86 family, the CPU is where all the action takes place. All computations occur inside the CPU. Data and CPU instructions reside in memory until required by the CPU. To the CPU, most I/O devices look like memory because the CPU can store data to an output device and read data from an input device.
37
Basic Microcomputer Design
control unit (CU) coordinates sequence of execution steps ALU performs arithmetic and bitwise processing
38
Central Processing Unit – The Processor
Block diagram of a imaginary CPU Central Processing Unit – The Processor Control registers ALU BIU Control General purpose registers Control Address Data Special (floating-point, flag, sse)
39
The processor It’s a state machine Has a set of hard-coded operations
Each operation has an associated code; an “opcode” Some examples are MOV, ADD, SUB, AND All it can do is move data or perform some calculation on data Very simple, right?
40
The processor - 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) 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 E.g. MOV, CMP, ADD, JMP
41
80x86 registers Small memory locations that are quickly accessible by the processor Hold data and results for operations Point to memory locations Contain status information about the results of operations General Purpose Special Registers AH AL Index Registers Accumulator AX Instr Pointer IP Stack Pointer SP BH BL Flags Base FLAG BX Base Pointer BP CH CL Count Segment Registers Dest Index DI CX Code Segment CS Source Index SI DH DL Data Data Segment DS DX Extra Segment ES SS Stack Segment
42
Register specifics Accumulator (AL, AH, AX)
Usually stores results from the ALU It “accumulates” totals from math operations General purpose Base (BL, BH, BX) Usually holds addresses – points to memory locations Count (CL, CH, CX, ECX) Counting and looping Certain instructions automatically decrement the count register Data (DL, DH, DX) Usually contains data for instructions Contain the most significant bytes of 16-bit Mul/div’s
43
Register specifics Stack pointer (SP) Used by stack operations
Usually you don’t want to mess with this one Base pointer (BP) Addresses stack memory Can be used to read subroutine arguments Source index (SI) Often used to address a source array or string data type Destination index (DI) Often used to address a destination array or string data type
44
Code segment (CS) Points to the area in memory where instructions are stored Instruction pointer (IP) An index into the code segment that points to the next instruction to be executed Data segment (DS) Points to the area in memory where data needed by a program is stored Stack segment (SS) Points to the area in memory containing the system’s FIFO stack.
45
The flag register Flags indicate the condition of the CPU as well as its operation Flag bits change after many arithmetic and logic instructions complete execution Example flags: C(carry) indicates carry after addition or borrow after subtraction in most significant bit O(overflow) is a condition that can occur when signed numbers are added or subtracted Z(zero) indicates that the result of an operation is zero
46
The flag register Bit No: 15 14 13 12 11 10 9 8 7 Flag: O D I T S
8086, 8088, 80186 80286 80386, 80486DX 80486SX 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 Bit No: Flag: O D I T S Bit No: Z A P C
47
The carry flag Carry indicates a carry in the H.O. bit after addition or a borrow in the H.O. bit after subtraction 8-bit example FFh + 1h = 00h, with carry 02h – 03h = FFh, with carry Carry is set when an unsigned number goes out of range (this is an unsigned arithmetic overflow) Some disk operations use the CF to indicate success (o) or failure (1). JC and JNC test this flag
48
The overflow flag Overflow 8-bit overflow example
condition that occurs when signed numbers go out of range For 8-bit, that range is from -128 to decimal 8-bit overflow example 7Fh + 1h = 80h, wanted = 128 but got -128 80h – 1h = 7F, we wanted -1 – 1 = -2 but got +127 JO and JNO test the OF
49
Overflows and carries examples
mov ax,0fffeh ; interpreted as unsigned add ax,3 ; C = 1, O = Unsigned Overflow Condition mov ax,0FFFEh ; -2 interpreted as signed add ax,3 ; C = 1, O = Okay as signed mov bx,07FFFh ; interpreted as signed add bx,1 ; C = 0, O = Signed Overflow Condition mov bx,07FFFh ; interpreted as unsigned add bx,1 ; C = 0, O = Okay as unsigned mov ax,07h ; 7 interpreted as either signed or unsigned add ax,03h ; C = 0, O = Okay as either
50
Instruction processing
Processing of an instruction by the microprocessor consists of three basic steps fetch instruction from the memory decode the instruction execute (usually involves accessing the memory for getting operands and storing results) Operation of an processor like the Intel 8085 Fetch 1 Decode 1 Execute 1 Fetch 2 Decode 2 Execute 2 …... Microprocessor Busy Idle Busy Busy Idle Busy …... Bus
51
Instruction processing
Modern microprocessors can process several instructions simultaneously at various stages of execution this ability is called pipelining Operation of a pipelined microprocessor like the Intel 80486 Fetch 1 Fetch 2 Fetch 3 Fetch 4 Store 1 Fetch 5 Fetch 6 Read 2 Fetch 7 Bus Unit Decode 1 Decode 2 Decode 3 Decode 4 Decode 5 Decode 6 Idle Idle Instruction Unit Execute 1 Execute 2 Execute 3 Execute 4 Execute 5 Execute 6 Idle Execution Unit Generate Address 1 Generate Address 2 Address Unit
52
Memory Organization System memory or RAM holds data and instruction opcodes that are being used by the CPU Organized in banks, usually even and odd Always byte addressable The 8088 and microprocessors have an eight bit data bus. This means that the CPU can transfer eight bits of data at a time.
53
Reading from Memory Multiple machine cycles are required when reading from memory, because it responds much more slowly than the CPU. The steps are: address placed on address bus Read Line (RD) set low CPU waits one cycle for memory to respond Read Line (RD) goes to 1, indicating that the data is on the data bus
54
Memory Access Examples
To execute the equivalent of the Pascal statement "Memory [125] := 0;" the CPU places the value zero on the data bus, the address 125 on the address bus, and asserts the write line (since the CPU is writing data to memory: To execute the equivalent of "CPU := Memory [125];" the CPU places the address 125 on the address bus, asserts the read line (since the CPU is reading data from memory), and then reads the resulting data from the data bus:
55
8-Bit Processor Memory Bit: the fundamental, indivisible data unit .
Either a 0 or a 1. Nibble: 4 bits Byte: 8 bits Word: 2 bytes Double word: 4 bytes Quad word: 8 bytes
56
Cache Memory High-speed expensive static RAM both inside and outside the CPU. Level-1 cache: inside the CPU Level-2 cache: outside the CPU Cache hit: when data to be read is already in cache memory Cache miss: when data to be read is not in cache memory.
57
Chapter 2 Assemble Language Programming (1)
58
Computer System (1) Hardware CPU Memory I/O Input Device CPU ALU
Control Unit Input Device Output Device Secondary Storage Main Memory
59
Computer System (2) Software System Program Application
Applications Hardware /Firmware Macro Processor Compiler Assembler File System OS Loader Linker Software System Program Application Application Program High-Level Program(HLL) Operating System(OS) Assembly Language(ASM) Machine Language(ML)
60
Computer System(3) The von Neumann architecture
Instruction, Data are stored in one memory Memory is addressed by location Sequential execution Memory bus . instruction data Register CPU instruction == machine code
61
Assembly Language(1) Assembly Language Machine Language
MOV AL, 21H ADD AL, 42H ADD AL, 13H END equivalent Assembly Language Low level programming language 1:1 match with machine language Machine language dependent, so, Architecture dependent Assembler Compile assembly code to machine code Machine Language Instruction Executable binary sequence Architecture (CPU) dependent
62
Assembly Language(2) Why needs?
To deepen our understanding of high-level languages based on computer architecture To save the memory for program
63
Sample Assembly Code ; Data segment DTSEG SEGMENT
msg DB 'Hello World’,’$' DTSEG ENDS ; Code segment CDSEG SEGMENT ASSUME CS:CDSEG, DS:DTSEG MAIN: MOV AX, DTSEG MOV DS, AX MOV AH, 02H MOV DL, 'A' INT 21H MOV AH, 09H MOV DX, OFFSET msg MOV AH, 4CH CDSEG ENDS END MAIN
64
Basic Grammar [Label:] OP-code [1st Operand] [, 2nd] [;comment]
label1: MOV AL, BL ; copy BL’s value to AL MOV DS, AX MOV AH, 02h MOV DX, offset msg Directives : ASSUME, EQU, DB, ORG, … ASSUME CS:code, DS:data Variable declaration <name> <type(DB, DW, DD, DQ, DT, …)> initial value data1 DB ‘A’ data2 DB ‘POSTECH$’ data3 DW 2345h data4 DB 10,13 data5 DB 16 DUP (?) data6 DB 4,?,4 DUP (13),’$’
65
Registers Intel 80x86 processors 8080/8085808680888028680386...
backward compatibility works from 8086 8086/286 register set General 16 AX, BX, CX, DX 8 AH, AL, BH, BL, CH, CL, DH, DL Pointer SP (stack pointer), BP (base pointer) Segment CS (code), DS (data), SS (stack), ES (extra) * AH, AL = higher, lower order byte of AX * Here, not all registers are mentioned.
66
Interrupt INT 21H DOS Interrupt
Program execution, Keyboard, Display, File system... Example Process termination AH : 4CH Display string until ‘$’ AH : 09H, DX : offset of ASCII string Display one character AH : 02H, DL : character Get a character in AL AH : 01H
67
MASM Microsoft Macro Assembler Tools For 80x86
For creating DOS and Windows applications Tools MASM: compiler LINK: linker
68
MASM
69
Exercise Input 3 characters and print out them. Ex)
Input three characters: abc Your input was: abc Tips (Details in the next lecture) int 21h with AH=01h Input a character with echo and store the input to AL int 21h with AH=0Ah : buffered keyboard input Store the string to DS:DX+2 add DX, 02h [DS:DX] = buffer size If you want to get n characters, buffer size should be n+1 due to one termination character (line feed = 10) [DS:DX+1] = length of the string
70
Register Set
71
8086 Register Set
72
8086 Register Set
73
8086 Register Set
74
8086 Register Set
75
Intel Segmented Memory Model for 20-bit Address Space
76
Intel Segmented Memory Model for 20-bit Address Space
77
Intel Segmented Memory Model for 20-bit Address Space
78
Intel Segmented Memory Model for 20-bit Address Space
79
Intel Segmented Memory Model for 20-bit Address Space
80
Intel Segmented Memory Model for 20-bit Address Space
81
Intel Segmented Memory Model for 20-bit Address Space
82
Intel Segmented Memory Model for 20-bit Address Space
83
How is segmented memory managed by the 8086 ?
85
Data Addressing Modes
86
8086-P4 Data-addressing Modes
87
MOV Format
88
Immediate Addressing
89
Register Addressing
90
Examples
91
Direct Data Addressing
92
Register Indirect Addressing
93
Displacement Addressing
94
Example of register indirect addressing
95
An array (TABLE) containing 50 bytes that are indirectly addressed through register BX
96
An example showing how base-plus-index addressing mode functions for MOV DX,[BX+DI] instruction
97
Base-Plus-Index Addressing
98
Examples of base-plus-index addressing
99
Example of base-plus-index addressing
100
Examples of register relative addressing
101
Register Relative Addressing
102
Addressing Array Data with Register Relative
103
Base Relative-Plus-Index Addressing
104
Addressing Arrays with Base Relative-plus-index
105
Example base relative-plus-index instructions
106
Base relativeplus-index addressing used to access a FILE that contains multiple records (REC)
107
Scaled-Index Addressing
108
Program Memory-Addressing Modes
110
Stack Memory-Addressing Modes
112
Chapter 3 80x86/88 Microprocessor
113
8088/8086 Hardware
114
VCC, GND and CLK
115
Address/Data Pins
116
Tri-state pin
117
Minimum mode control signals
118
Maximum mode control signals
119
8088 pins summary
120
Latch for address lines
121
Transceiver for data lines
122
De-multiplexing address and data
123
Clock generator: 8284A
124
Bus timing
125
Bus cycles
126
Wait state and READY signal
127
Detailed read timing
128
I/O interface
129
8088 I/O interface
130
Parallel and serial data transfer
131
Memory Devices
132
Types of Memories
133
Memory Pin Connections
134
Types of ROM
135
Read-Only Memory
137
Timing Diagram of 2716 EPROM
138
Timing Diagrams of TMS4016, 2Kx8 SRAM
141
RAS and CAS for DRAM
142
DRAM Circuit Boards
143
10-2 Address Decoding
145
3-to-8 Line Decoder (74LS138)
146
8088 and Memory Interface
148
Dynamic RAM
149
Interfacing Flash Memory to the 8088
150
DRAM Internal and Refresh
151
DRAM Controllers
152
Various Types of DRAM
154
DRAM refreshing operation (continued)
155
SIMM
156
DIMM
157
Matching memory with data bus
158
Memory interface in 8088: Example 1
159
Memory interface in 8088: Example 2
160
DRAM: advanced access modes
161
FPM, EDO & SDRAM
162
Chapter 4 Assemble Language Programming (2)
163
Data Transfer Instructions
Operand Types Instruction Operand Notation Direct Memory Operands MOV Instruction Zero & Sign Extension XCHG Instruction Direct-Offset Instructions
164
Operand Types Three basic types of operands:
Immediate – a constant integer (8, 16, or 32 bits) value is encoded within the instruction Register – the name of a register register name is converted to a number and encoded within the instruction Memory – reference to a location in memory memory address is encoded within the instruction, or a register holds the address of a memory location
165
Instruction Operand Notation
166
Direct Memory Operands
A direct memory operand is a named reference to storage in memory The named reference (label) is automatically dereferenced by the assembler .data var1 BYTE 10h .code mov al,var1 ; AL = 10h mov al,[var1] ; AL = 10h alternate format
167
The MOV instruction MOV moves data from one place to another register to register Register to memory Memory to register Immediate data to register NEVER memory to memory Syntax: MOV destination, source Destination and source can be many different things or combination of things. What these things are determines the Addressing Mode. [label:] MOV register/memory, register/memory/immediate
168
MOV Instruction Move from source to destination. Syntax:
MOV destination,source No more than one memory operand permitted CS, EIP, and IP cannot be the destination No immediate to segment moves .data count BYTE 100 wVal WORD 2 .code mov bl,count mov ax,wVal mov count,al mov al,wVal ; error mov ax,count ; error mov eax,count ; error
169
Register Moves MOV EDX, ECX ; register – to register MOV ES,AX ; register – to segment register MOV BYTEFLD , DH : register – to memory , direct MOV [DI], BX ; register to memory, indirect 2. Immediate Moves MOV CX, 40H ; Immediate –to- register MOV BYTEFLD, 25 ; Immediate-to-memory, direct MOV WORDFLD [BX], 16H ; Immediate –to- memory , indirect 3. Direct Memory Moves MOV CH,BYTEFLD ; Memory- to- register, direct MOV CX, WORDFLD[BX] ; Memory-to register, indirect 4. Segment Register Moves MOV AX,DS ; Segment register –to –register MOV WORDFD, DS ; Segment register –to-memory
170
Memory example - MOVing
mov ax, cs ; make data seg same as code seg mov ds, ax mov ax, [myvar2] ; move value of myvar2 to ax ; same as mov ax, [2] ; ax now contains 04D2h mov si, myvar2 ; si now points to myvar2 ; it contains 0002h mov ax, [si] ; move value pointed to by si to ax ; ax again contains 04D2h ; this was an indirect reference
171
Memory example - MOVing
; Memory can be addressed using four registers only!!! ; SI -> offsets from DS ; DI -> offsets from DS ; BX -> offsets from DS ; BP -> offsets from SS mov ax, [bx] ; ax = word in memory pointed to by bx mov al, [bx] ; al = byte in memory pointed to by bx mov ah, [si] ; ah = byte in memory pointed to by si mov cx, [di] ; cx = word in memory pointed to by di mov ax, [bp] ; ax = [SS:BP] Stack Operation! ; In addition, BX + SI, BX + DI, BP + SI, and BP + DI are allowed mov ax, [bx + si] ; ax = [ds:bx+si] mov ch, [bp + di] ; ch = [ss:bp+di]
172
Memory example - MOVing
; Furthermore, a fixed 8- or 16-bit displacement can be added mov ax, [23h] ; ax = word at [DS:23h] mov ah, [bx + 5] ; ah = byte at [DS:bx+5] mov ax, [bx + si + 107] ; ax = word at [DS:bx+si+107] mov ax, [bp + di + 42] ; ax = word at [SS:bp+di+42] ; Remember that memory to memory moves are illegal! mov [bx], [si] ; BAD BAD BAD mov [di], [si] ; BAD BAD BAD ; Special case with stack operations pop word [myvar] ; moves data from top of stack to ; memory variable myvar
173
Your turn . . . Explain why each of the following MOV statements are invalid: .data bVal BYTE 100 bVal2 BYTE ? wVal WORD 2 dVal DWORD 5 .code mov ds,45 ; a. mov esi,wVal ; b. mov eip,dVal ; c. mov 25,bVal ; d. mov bVal2,bVal ; e.
174
The destination must be a register.
Zero Extension When you copy a smaller value into a larger destination, the MOVZX instruction fills (extends) the upper half of the destination with zeros. mov bl, b movzx ax,bl ; zero-extension The destination must be a register.
175
The destination must be a register.
Sign Extension The MOVSX instruction fills the upper half of the destination with a copy of the source operand's sign bit. mov bl, b movsx ax,bl ; sign extension The destination must be a register.
176
XCHG Instruction XCHG exchanges the values of two operands. At least one operand must be a register. No immediate operands are permitted. .data var1 WORD 1000h var2 WORD 2000h .code xchg ax,bx ; exchange 16-bit regs xchg ah,al ; exchange 8-bit regs xchg var1,bx ; exchange mem, reg xchg eax,ebx ; exchange 32-bit regs xchg var1,var2 ; error: two memory operands
177
Direct-Offset Operands
A constant offset is added to a data label to produce an effective address (EA). The address is dereferenced to get the value inside its memory location. .data arrayB BYTE 10h,20h,30h,40h .code mov al,arrayB+1 ; AL = 20h mov al,[arrayB+1] ; alternative notation Q: Why doesn't arrayB+1 produce 11h?
178
Direct – Offset Addressing
.data array DB 0Ah, 0Bh, 0Ch, 0Dh .code MOV AL,array ; AL=0Ah MOV BL,array+1 ;BL = 0Bh MOV CL, array+2 ; CL=0Ch MOV DL, array +3 ; DL =0Dh
179
Direct-Offset Operands (cont)
A constant offset is added to a data label to produce an effective address (EA). The address is dereferenced to get the value inside its memory location. .data arrayW WORD 1000h,2000h,3000h arrayD DWORD 1,2,3,4 .code mov ax,[arrayW+2] ; AX = 2000h mov ax,[arrayW+4] ; AX = 3000h mov eax,[arrayD+4] ; EAX = h ; Will the following statements assemble? mov ax,[arrayW-2] ; ?? mov eax,[arrayD+16] ; ?? What will happen when they run?
180
Your turn. . . Write a program that rearranges the values of three doubleword values in the following array as: 3, 1, 2. .data arrayD DWORD 1,2,3 Step1: copy the first value into EAX and exchange it with the value in the second position. mov eax,arrayD xchg eax,[arrayD+4] Step 2: Exchange EAX with the third array value and copy the value in EAX to the first array position. xchg eax,[arrayD+8] mov arrayD,eax
181
Evaluate this . . . We want to write a program that adds the following three bytes: .data myBytes BYTE 80h,66h,0A5h What is your evaluation of the following code? mov al,myBytes add al,[myBytes+1] add al,[myBytes+2] What is your evaluation of the following code? mov ax,myBytes add ax,[myBytes+1] add ax,[myBytes+2] Any other possibilities?
182
Evaluate this (cont) .data myBytes BYTE 80h,66h,0A5h How about the following code. Is anything missing? movzx ax,myBytes mov bl,[myBytes+1] add ax,bx mov bl,[myBytes+2] add ax,bx ; AX = sum Yes: Move zero to BX before the MOVZX instruction.
183
Addition and Subtraction
INC and DEC Instructions ADD and SUB Instructions NEG Instruction Implementing Arithmetic Expressions Flags Affected by Arithmetic Zero Sign Carry Overflow
184
INC and DEC Instructions
Add 1, subtract 1 from destination operand operand may be register or memory INC destination Logic: destination destination + 1 DEC destination Logic: destination destination – 1
185
INC and DEC Examples .data myWord WORD 1000h myDword DWORD 10000000h
.code inc myWord ; 1001h dec myWord ; 1000h inc myDword ; h mov ax,00FFh inc ax ; AX = 0100h inc al ; AX = 0000h
186
Your turn... Show the value of the destination operand after each of the following instructions executes: .data myByte BYTE 0FFh, 0 .code mov al,myByte ; AL = mov ah,[myByte+1] ; AH = dec ah ; AH = inc al ; AL = dec ax ; AX = FFh 00h FEFF
187
ADD and SUB Instructions
ADD destination, source Logic: destination destination + source SUB destination, source Logic: destination destination – source Same operand rules as for the MOV instruction
188
ADD and SUB Examples .data var1 DWORD 10000h var2 DWORD 20000h
.code ; ---EAX--- mov eax,var1 ; h add eax,var2 ; h add ax,0FFFFh ; 0003FFFFh add eax,1 ; h sub ax,1 ; 0004FFFFh
189
NEG (negate) Instruction
Reverses the sign of an operand. Operand can be a register or memory operand. .data valB BYTE -1 valW WORD .code mov al,valB ; AL = -1 neg al ; AL = +1 neg valW ; valW = Suppose AX contains –32,768 and we apply NEG to it. Will the result be valid?
190
NEG Instruction and the Flags
The processor implements NEG using the following internal operation: SUB 0,operand Any nonzero operand causes the Carry flag to be set. .data valB BYTE 1,0 valC SBYTE -128 .code neg valB ; CF = 1, OF = 0 neg [valB + 1] ; CF = 0, OF = 0 neg valC ; CF = 1, OF = 1
191
Implementing Arithmetic Expressions
HLL compilers translate mathematical expressions into assembly language. You can do it also. For example: Rval = -Xval + (Yval – Zval) Rval DWORD ? Xval DWORD 26 Yval DWORD 30 Zval DWORD 40 .code mov eax,Xval neg eax ; EAX = -26 mov ebx,Yval sub ebx,Zval ; EBX = -10 add eax,ebx mov Rval,eax ; -36
192
Your turn... Translate the following expression into assembly language. Do not permit Xval, Yval, or Zval to be modified: Rval = Xval - (-Yval + Zval) Assume that all values are signed doublewords. mov ebx,Yval neg ebx add ebx,Zval mov eax,Xval sub eax,ebx mov Rval,eax
193
Flags Affected by Arithmetic
The ALU has a number of status flags that reflect the outcome of arithmetic (and bitwise) operations based on the contents of the destination operand Essential flags: Zero flag – set when destination equals zero Sign flag – set when destination is negative Carry flag – set when unsigned value is out of range Overflow flag – set when signed value is out of range The MOV instruction never affects the flags.
194
arithmetic & bitwise operations
Concept Map CPU part of executes executes ALU conditional jumps arithmetic & bitwise operations attached to used by provide affect status flags branching logic You can use diagrams such as these to express the relationships between assembly language concepts.
195
Zero Flag (ZF) The Zero flag is set when the result of an operation produces zero in the destination operand. mov cx,1 sub cx,1 ; CX = 0, ZF = 1 mov ax,0FFFFh inc ax ; AX = 0, ZF = 1 inc ax ; AX = 1, ZF = 0 Remember... A flag is set when it equals 1. A flag is clear when it equals 0.
196
Sign Flag (SF) The Sign flag is set when the destination operand is negative. The flag is clear when the destination is positive. mov cx,0 sub cx,1 ; CX = -1, SF = 1 add cx,2 ; CX = 1, SF = 0 The sign flag is a copy of the destination's highest bit: mov al,0 sub al, ; AL = b, SF = 1 add al, ; AL = b, SF = 0
197
Signed and Unsigned Integers A Hardware Viewpoint
All CPU instructions operate exactly the same on signed and unsigned integers The CPU cannot distinguish between signed and unsigned integers YOU, the programmer, are solely responsible for using the correct data type with each instruction Added Slide. Gerald Cahill, Antelope Valley College
198
Overflow and Carry Flags A Hardware Viewpoint
How the ADD instruction modifies OF and CF: OF = (carry out of the MSB) XOR (carry into the MSB) CF = (carry out of the MSB) How the SUB instruction modifies OF and CF: NEG the source and ADD it to the destination CF = INVERT (carry out of the MSB) MSB = Most Significant Bit (high-order bit) XOR = eXclusive-OR operation NEG = Negate (same as SUB 0,operand ) Added Slide. Gerald Cahill, Antelope Valley College
199
Carry Flag (CF) The Carry flag is set when the result of an operation generates an unsigned value that is out of range (too big or too small for the destination operand). mov al,0FFh add al,1 ; CF = 1, AL = 00 ; Try to go below zero: mov al,0 sub al,1 ; CF = 1, AL = FF
200
Your turn . . . For each of the following marked entries, show the values of the destination operand and the Sign, Zero, and Carry flags: mov ax,00FFh add ax,1 ; AX= SF= ZF= CF= sub ax,1 ; AX= SF= ZF= CF= add al,1 ; AL= SF= ZF= CF= mov bh,6Ch add bh,95h ; BH= SF= ZF= CF= mov al,2 sub al,3 ; AL= SF= ZF= CF= 0100h 00FFh 00h 01h FFh
201
Overflow Flag (OF) The Overflow flag is set when the signed result of an operation is invalid or out of range. ; Example 1 mov al,+127 add al,1 ; OF = 1, AL = ?? ; Example 2 mov al,7Fh ; OF = 1, AL = 80h add al,1 The two examples are identical at the binary level because 7Fh equals To determine the value of the destination operand, it is often easier to calculate in hexadecimal.
202
A Rule of Thumb When adding two integers, remember that the Overflow flag is only set when . . . Two positive operands are added and their sum is negative Two negative operands are added and their sum is positive What will be the values of the Overflow flag? mov al,80h add al,92h ; OF = mov al,-2 add al,+127 ; OF =
203
Your turn . . . What will be the values of the given flags after each operation? mov al,-128 neg al ; CF = OF = mov ax,8000h add ax,2 ; CF = OF = mov ax,0 sub ax,2 ; CF = OF = mov al,-5 sub al,+125 ; OF = 1
204
Data-Related Operators and Directives
OFFSET Operator PTR Operator TYPE Operator LENGTHOF Operator SIZEOF Operator LABEL Directive
205
OFFSET Operator OFFSET returns the distance in bytes, of a label from the beginning of its enclosing segment Protected mode: 32 bits Real mode: 16 bits The Protected-mode programs we write only have a single segment (we use the flat memory model).
206
OFFSET Examples Let's assume that the data segment begins at h: .data bVal BYTE ? wVal WORD ? dVal DWORD ? dVal2 DWORD ? .code mov esi,OFFSET bVal ; ESI = mov esi,OFFSET wVal ; ESI = mov esi,OFFSET dVal ; ESI = mov esi,OFFSET dVal2 ; ESI =
207
Relating to C/C++ The value returned by OFFSET is a pointer. Compare the following code written for both C++ and assembly language: ; C++ version: char array[1000]; char * p = array; .data array BYTE 1000 DUP(?) .code mov esi,OFFSET array ; ESI is p
208
PTR Operator Overrides the default type of a label (variable). Provides the flexibility to access part of a variable. .data myDouble DWORD h .code mov ax,myDouble ; error – why? mov ax,WORD PTR myDouble ; loads 5678h mov WORD PTR myDouble,4321h ; saves 4321h Recall that little endian order is used when storing data in memory (see Section 3.4.9).
209
PTR Operator Examples .data myDouble DWORD 12345678h
mov al,BYTE PTR myDouble ; AL = 78h mov al,BYTE PTR [myDouble+1] ; AL = 56h mov al,BYTE PTR [myDouble+2] ; AL = 34h mov ax,WORD PTR myDouble ; AX = 5678h mov ax,WORD PTR [myDouble+2] ; AX = 1234h
210
PTR Operator (cont) PTR can also be used to combine elements of a smaller data type and move them into a larger operand. The CPU will automatically reverse the bytes. .data myBytes BYTE 12h,34h,56h,78h .code mov ax,WORD PTR [myBytes] ; AX = 3412h mov ax,WORD PTR [myBytes+2] ; AX = 7856h mov eax,DWORD PTR myBytes ; EAX = h
211
Your turn . . . Write down the value of each destination operand:
.data varB BYTE 65h,31h,02h,05h varW WORD 6543h,1202h varD DWORD h .code mov ax,WORD PTR [varB+2] ; a. mov bl,BYTE PTR varD ; b. mov bl,BYTE PTR [varW+2] ; c. mov ax,WORD PTR [varD+2] ; d. mov eax,DWORD PTR varW ; e. 0502h 78h 02h 1234h h
212
TYPE Operator The TYPE operator returns the size, in bytes, of a single element of a data declaration. .data var1 BYTE ? var2 WORD ? var3 DWORD ? var4 QWORD ? .code mov eax,TYPE var1 ; 1 mov eax,TYPE var2 ; 2 mov eax,TYPE var3 ; 4 mov eax,TYPE var4 ; 8
213
LENGTHOF Operator The LENGTHOF operator counts the number of elements in a single data declaration. .data LENGTHOF byte1 BYTE 10,20,30 ; 3 array1 WORD 30 DUP(?),0,0 ; 32 array2 WORD 5 DUP(3 DUP(?)) ; 15 array3 DWORD 1,2,3,4 ; 4 digitStr BYTE " ",0 ; 9 .code mov ecx,LENGTHOF array1 ; 32
214
SIZEOF Operator The SIZEOF operator returns a value that is equivalent to multiplying LENGTHOF by TYPE. .data SIZEOF byte1 BYTE 10,20,30 ; 3 array1 WORD 30 DUP(?),0,0 ; 64 array2 WORD 5 DUP(3 DUP(?)) ; 30 array3 DWORD 1,2,3,4 ; 16 digitStr BYTE " ",0 ; 9 .code mov ecx,SIZEOF array1 ; 64
215
Spanning Multiple Lines (1 of 2)
A data declaration spans multiple lines if each line (except the last) ends with a comma. The LENGTHOF and SIZEOF operators include all lines belonging to the declaration: .data array WORD 10,20, 30,40, 50,60 .code mov eax,LENGTHOF array ; 6 mov ebx,SIZEOF array ; 12
216
Spanning Multiple Lines (2 of 2)
In the following example, array identifies only the first WORD declaration. Compare the values returned by LENGTHOF and SIZEOF here to those in the previous slide: .data array WORD 10,20 WORD 30,40 WORD 50,60 .code mov eax,LENGTHOF array ; 2 mov ebx,SIZEOF array ; 4
217
LABEL Directive Assigns an alternate label name and type to an existing storage location LABEL does not allocate any storage of its own Removes the need for the PTR operator .data dwList LABEL DWORD wordList LABEL WORD intList BYTE 00h,10h,00h,20h .code mov eax,dwList ; h mov cx,wordList ; 1000h mov dl,intList ; 00h
218
Indirect Addressing Indirect Operands Array Sum Example
Indexed Operands Pointers
219
Indirect Addressing Modes
Problem: We want to add 50 word values in a list called List Solution: ??? mov AX, add AX, List add AX, List add AX, List+98 What if there were 5000 words?
220
Indirect Addressing Modes
Put the offset of List in a register. Add the value whose offset is in the register. Point register to next value and repeat as needed.
221
Indirect Addressing Mode
Notation: [reg] where reg is BX, BP, SI, or DI in In 32 bit mode, AX, CX, or DX can also be used Example: mov AX, [BX] Move the value whose address is in BX to AX Move the value pointed by BX to AX
222
Indirect Addressing Modes
mov AX, [SI] Memory 600 SI 600 25 AX
223
Indirect Addressing - Indirect Operands
For example, if we create a string in memory at location 0200 and set BX to the offset of the string, we can process any element in the string by adding its offset to BX. The letter “F” is at offset 5 in the following example: .data aString db “ABCDEFG” .code MOV BX, offset aString ; BX=0200 ADD BX,5 ; BX=0205 MOV DL, [BX] ; DL=”F”
224
Indirect Addressing Modes: Example
.data List dw 1, 3, 10, 6, 2, 9, 2, 8, Number = ($ - List)/2 .code … ; sum values in list mov AX, 0 ; sum = mov CX, Number ; number of values mov SI, OFFSET List ; ptr to List L3: add AX, [SI] ; add value add SI, 2 ; point to next value loop L3 ; repeat as needed
225
Indirect Addressing Modes
The absolute memory address is formed by adding the offset to 10h times a segment register Offset in Segment register Type BX DS Base BP SS Base SI DS Index DI DS Index Problem: Print the characters in String one at a time. Solution: Next slide
226
Indirect Addressing Modes
String db "the words" Long = $ - String … ; Print string 1 character at a time (function 2, int 21h) mov CX, Long ; CX <- number char mov SI, OFFSET String; point to String L9: mov DL, [SI] ; get char mov AH, ; print char int 21h inc SI ; point to next char loop L ; repeat
227
Indirect Operands (1 of 2)
An indirect operand holds the address of a variable, usually an array or string. It can be dereferenced (just like a pointer). .data val1 BYTE 10h,20h,30h .code mov esi,OFFSET val1 mov al,[esi] ; dereference ESI (AL = 10h) inc esi mov al,[esi] ; AL = 20h mov al,[esi] ; AL = 30h
228
Indirect Operands (2 of 2)
Use PTR to clarify the size attribute of a memory operand. .data myCount WORD 0 .code mov esi,OFFSET myCount inc [esi] ; error: ambiguous inc WORD PTR [esi] ; ok Should PTR be used here? add [esi],20 yes, because [esi] could point to a byte, word, or doubleword
229
Array Sum Example Indirect operands are ideal for traversing an array. Note that the register in brackets must be incremented by a value that matches the array type. .data arrayW WORD 1000h,2000h,3000h .code mov esi,OFFSET arrayW mov ax,[esi] add esi,2 ; or: add esi,TYPE arrayW add ax,[esi] add esi,2 add ax,[esi] ; AX = sum of the array ToDo: Modify this example for an array of doublewords.
230
Indexed Operands An indexed operand adds a constant to a register to generate an effective address. There are two notational forms: [label + reg] label[reg] .data arrayW WORD 1000h,2000h,3000h .code mov esi,0 mov ax,[arrayW + esi] ; AX = 1000h mov ax,arrayW[esi] ; alternate format add esi,2 add ax,[arrayW + esi] etc. ToDo: Modify this example for an array of doublewords.
231
Index Scaling* You can scale an indirect or indexed operand to the offset of an array element. This is done by multiplying the index by the array's TYPE: .data arrayB BYTE 0,1,2,3,4,5 arrayW WORD 0,1,2,3,4,5 arrayD DWORD 0,1,2,3,4,5 .code mov esi,4 mov al,arrayB[esi*TYPE arrayB] ; 04 mov bx,arrayW[esi*TYPE arrayW] ; 0004 mov edx,arrayD[esi*TYPE arrayD] ; * Not in the book
232
Based Indexed Addressing Modes
Example: The array of 8bit integers. If this array is located at offset 0150 and we set BX to the beginning of the second row and set SI to the offset of the third column, the offset represented by BX +SI is 0157. .data ROWSIZE = 5 Array DB 10H,20H, 30H, 40H, 50H, 60H … .code MOV BX, offset array ; point to the array at 0150 ADD BX, ROWSIZE ; choose second row MOV SI,2 ; choose third column MOV AL, [BX+SI] ; get the value at 0157
233
Indirect Addressing Based and Indexed Addressing
mov AX, List[SI] Memory 100 List List+2 List+4 List+6 List+8 List+10 List+12 SI 4 100 AX
234
Indirect Addressing Based and Indexed Addressing
mov SI, OFFSET List mov AX, 4[SI] Memory 100 List List+2 List+4 List+6 List+8 List+10 List+12 SI OFFSET List 100 AX
235
Indexed Addressing Modes: Example
.data List dw 1, 3, 10, 6, 2, 9, 2, 8, Number = ($ - List)/2 .code mov AX, 0 ; sum = mov CX, Number ; number of values mov SI, 0 ; "Subscript" L8: add AX, List[SI] ; add value add SI, 2 ; point to next value loop L8 ; repeat as needed
236
Indirect Addressing Based - Indexed Addressing
Add a base register and index register to get offset (32-bit mode allows using any two registers) Great for 2-D arrays Notation [reg + reg]
237
4.4 Indirect Addressing Based - Indexed Addressing
mov BX, OFFSET List mov SI, 4 mov AX, [BX+SI] Memory 100 List List+2 List+4 List+6 List+8 List+10 List+12 OFFSET List BX + 100 SI 4 AX
238
4.4 Indirect Addressing Based - Indexed Addressing
Array dd 11, 12, 13, 14, dd 21, 22, 23, 24, dd 31, 32, 33, 34, 35 NumCol = … mov EBX, OFFSET Array add EBX, (NumCol*4) * mov ESI, 4* mov EAX, [EBX+ESI] Bytes per row 3rd row 4th column Bytes per element EAX 34
239
Indirect Addressing Based - Indexed with Displacement
Like based-indexed but with a displacement Effective offset is reg + reg + displacement Notation: constant[reg][reg] Recall: variables are [reg + reg + constant] constants to MASM constant[reg + reg] Example: mov Array[BX][SI], 10
240
Indirect Addressing Based - Indexed with Displacement
Array dd 11, 12, 13, 14, dd 21, 22, 23, 24, dd 31, 32, 33, 34, 35 NumCol = … mov EBX, (NumCol*4) * mov ESI, 4* mov EAX, Array[EBX+ESI] Bytes per row 3rd row 4th column Bytes per element EAX 34
241
Pointers You can declare a pointer variable that contains the offset of another variable. .data arrayW WORD 1000h,2000h,3000h ptrW DWORD arrayW .code mov esi,ptrW mov ax,[esi] ; AX = 1000h Alternate format: ptrW DWORD OFFSET arrayW
242
JMP and LOOP Instructions
JMP Instruction LOOP Instruction LOOP Example Summing an Integer Array Copying a String
243
JMP Instruction JMP is an unconditional jump to a label that is usually within the same procedure. Syntax: JMP target Logic: EIP target Example: top: . jmp top A jump outside the current procedure must be to a special type of label called a global label (see Section for details).
244
LOOP Instruction The LOOP instruction creates a counting loop
Syntax: LOOP target Logic: ECX ECX – 1 if ECX != 0, jump to target Implementation: The assembler calculates the distance, in bytes, between the offset of the following instruction and the offset of the target label. It is called the relative offset. The relative offset is added to EIP.
245
LOOP Example The following loop calculates the sum of the integers : offset machine code source code B mov ax,0 B mov ecx,5 C1 L1: add ax,cx C E2 FB loop L1 E When LOOP is assembled, the current location = E (offset of the next instruction). –5 (FBh) is added to the the current location, causing a jump to location : E + FB
246
Your turn . . . If the relative offset is encoded in a single signed byte, (a) what is the largest possible backward jump? (b) what is the largest possible forward jump? -128 +127
247
Your turn . . . What will be the final value of AX? 10
mov ax,6 mov ecx,4 L1: inc ax loop L1 What will be the final value of AX? 10 How many times will the loop execute? mov ecx,0 X2: inc ax loop X2 4,294,967,296
248
Nested Loop If you need to code a loop within a loop, you must save the outer loop counter's ECX value. In the following example, the outer loop executes 100 times, and the inner loop 20 times. .data count DWORD ? .code mov ecx,100 ; set outer loop count L1: mov count,ecx ; save outer loop count mov ecx,20 ; set inner loop count L2: . . loop L2 ; repeat the inner loop mov ecx,count ; restore outer loop count loop L1 ; repeat the outer loop
249
Summing an Integer Array
The following code calculates the sum of an array of 16-bit integers. .data intarray WORD 100h,200h,300h,400h .code mov edi,OFFSET intarray ; address of intarray mov ecx,LENGTHOF intarray ; loop counter mov ax,0 ; zero the accumulator L1: add ax,[edi] ; add an integer add edi,TYPE intarray ; point to next integer loop L1 ; repeat until ECX = 0
250
Your turn . . . What changes would you make to the program on the previous slide if you were summing a doubleword array?
251
Copying a String The following code copies a string from source to target: .data source BYTE "This is the source string",0 target BYTE SIZEOF source DUP(0) .code mov esi,0 ; index register mov ecx,SIZEOF source ; loop counter L1: mov al,source[esi] ; get char from source mov target[esi],al ; store it in the target inc esi ; move to next character loop L1 ; repeat for entire string good use of SIZEOF
252
Your turn . . . Rewrite the program shown in the previous slide, using indirect addressing rather than indexed addressing.
253
Link Library Overview A file containing procedures that have been compiled into machine code constructed from one or more OBJ files To build a library, . . . start with one or more ASM source files assemble each into an OBJ file create an empty library file (extension .LIB) add the OBJ file(s) to the library file, using the Microsoft LIB utility Take a quick look at Irvine32.asm by clicking on Examples at the bottom of this screen.
254
Calling a Library Procedure
Call a library procedure using the CALL instruction. Some procedures require input arguments. The INCLUDE directive copies in the procedure prototypes (declarations). The following example displays "1234" on the console: INCLUDE Irvine32.inc .code mov eax,1234h ; input argument call WriteHex ; show hex number call Crlf ; end of line
255
Linking to a Library Your programs link to Irvine32.lib using the linker command inside a batch file named make32.bat. Notice the two LIB files: Irvine32.lib, and kernel32.lib the latter is part of the Microsoft Win32 Software Development Kit (SDK)
256
Library Procedures - Overview (1 of 3)
Clrscr - Clears the console and locates the cursor at the upper left corner. Crlf - Writes an end of line sequence to standard output. Delay - Pauses the program execution for a specified n millisecond interval. DumpMem - Writes a block of memory to standard output in hexadecimal. DumpRegs - Displays the EAX, EBX, ECX, EDX, ESI, EDI, EBP, ESP, EFLAGS, and EIP registers in hexadecimal. Also displays the Carry, Sign, Zero, and Overflow flags. GetCommandtail - Copies the program’s command-line arguments (called the command tail) into an array of bytes. GetMseconds - Returns the number of milliseconds that have elapsed since midnight.
257
Library Procedures - Overview (2 of 3)
Gotoxy - Locates cursor at row and column on the console. Random32 - Generates a 32-bit pseudorandom integer in the range 0 to FFFFFFFFh. Randomize - Seeds the random number generator. RandomRange - Generates a pseudorandom integer within a specified range. ReadChar - Reads a single character from standard input. ReadHex - Reads a 32-bit hexadecimal integer from standard input, terminated by the Enter key. ReadInt - Reads a 32-bit signed decimal integer from standard input, terminated by the Enter key. ReadString - Reads a string from standard input, terminated by the Enter key.
258
Library Procedures - Overview (3 of 3)
SetTextColor - Sets the foreground and background colors of all subsequent text output to the console. WaitMsg - Displays message, waits for Enter key to be pressed. WriteBin - Writes an unsigned 32-bit integer to standard output in ASCII binary format. WriteChar - Writes a single character to standard output. WriteDec - Writes an unsigned 32-bit integer to standard output in decimal format. WriteHex - Writes an unsigned 32-bit integer to standard output in hexadecimal format. WriteInt - Writes a signed 32-bit integer to standard output in decimal format. WriteString - Writes a null-terminated string to standard output.
259
Example 1 Clear the screen, delay the program for 500 milliseconds, and dump the registers and flags. .code call Clrscr mov eax,500 call Delay call DumpRegs EAX= EBX= ECX=000000FF EDX= ESI= EDI= EBP= E ESP=000000F6 EIP= EFL= CF=0 SF=1 ZF=0 OF=0 Sample output:
260
Example 2 Display a null-terminated string and move the cursor to the beginning of the next screen line. .data str1 BYTE "Assembly language is easy!",0 .code mov edx,OFFSET str1 call WriteString call Crlf
261
Example 2a Display a null-terminated string and move the cursor to the beginning of the next screen line (use embedded CR/LF) .data str1 BYTE "Assembly language is easy!",0Dh,0Ah,0 .code mov edx,OFFSET str1 call WriteString
262
Example 3 Display an unsigned integer in binary, decimal, and hexadecimal, each on a separate line. IntVal = 35 .code mov eax,IntVal call WriteBin ; display binary call Crlf call WriteDec ; display decimal call WriteHex ; display hexadecimal 35 23 Sample output:
263
Example 4 Input a string from the user. EDX points to the string and ECX specifies the maximum number of characters the user is permitted to enter. .data fileName BYTE 80 DUP(0) .code mov edx,OFFSET fileName mov ecx,SIZEOF fileName – 1 call ReadString A null byte is automatically appended to the string.
264
Example 5 Generate and display ten pseudorandom signed integers in the range 0 – 99. Pass each integer to WriteInt in EAX and display it on a separate line. .code mov ecx,10 ; loop counter L1: mov eax,100 ; ceiling value call RandomRange ; generate random int call WriteInt ; display signed int call Crlf ; goto next display line loop L1 ; repeat loop
265
Example 6 Display a null-terminated string with yellow characters on a blue background. .data str1 BYTE "Color output is easy!",0 .code mov eax,yellow + (blue * 16) call SetTextColor mov edx,OFFSET str1 call WriteString call Crlf The background color is multiplied by 16 before being added to the foreground color.
266
Stack Operations Runtime Stack PUSH Operation POP Operation
PUSH and POP Instructions Using PUSH and POP Example: Reversing a String Related Instructions
267
Runtime Stack Imagine a stack of plates . . .
plates are only added to the top plates are only removed from the top LIFO structure
268
Navigating a Maze
269
Runtime Stack Managed by the CPU, using two registers
SS (stack segment) ESP (stack pointer) * * SP in Real-address mode
270
PUSH Operation (1 of 2) A 32-bit push operation decrements the stack pointer by 4 and copies a value into the location pointed to by the stack pointer.
271
PUSH Operation (2 of 2) Same stack after pushing two more integers:
The stack grows downward. The area below ESP is always available (unless the stack has overflowed).
272
POP Operation Copies value at stack[ESP] into a register or variable.
Adds n to ESP, where n is either 2 or 4. value of n depends on the attribute of the operand receiving the data
273
PUSH and POP Instructions
PUSH syntax: PUSH r/m16 PUSH r/m32 PUSH imm32 POP syntax: POP r/m16 POP r/m32
274
Using PUSH and POP Save and restore registers when they contain important values. PUSH and POP instructions occur in the opposite order. push esi ; push registers push ecx push ebx mov esi,OFFSET dwordVal ; display some memory mov ecx,LENGTHOF dwordVal mov ebx,TYPE dwordVal call DumpMem pop ebx ; restore registers pop ecx pop esi
275
Example: Nested Loop Remember the nested loop we created on page 129? It's easy to push the outer loop counter before entering the inner loop: mov ecx,100 ; set outer loop count L1: ; begin the outer loop push ecx ; save outer loop count mov ecx,20 ; set inner loop count L2: ; begin the inner loop ; loop L2 ; repeat the inner loop pop ecx ; restore outer loop count loop L1 ; repeat the outer loop
276
Example: Reversing a String
Use a loop with indexed addressing Push each character on the stack Start at the beginning of the string, pop the stack in reverse order, insert each character back into the string Source code Q: Why must each character be put in EAX before it is pushed? Because only word (16-bit) or doubleword (32-bit) values can be pushed on the stack.
277
Your turn . . . Using the String Reverse program as a starting point,
#1: Modify the program so the user can input a string containing between 1 and 50 characters. #2: Modify the program so it inputs a list of 32-bit integers from the user, and then displays the integers in reverse order.
278
Related Instructions PUSHFD and POPFD
push and pop the EFLAGS register PUSHAD pushes the 32-bit general-purpose registers on the stack order: EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI POPAD pops the same registers off the stack in reverse order PUSHA and POPA do the same for 16-bit registers
279
Your Turn . . . Write a program that does the following:
Assigns integer values to EAX, EBX, ECX, EDX, ESI, and EDI Uses PUSHAD to push the general-purpose registers on the stack Using a loop, your program should pop each integer from the stack and display it on the screen
280
Defining and Using Procedures
Creating Procedures Documenting Procedures Example: SumOf Procedure CALL and RET Instructions Nested Procedure Calls Local and Global Labels Procedure Parameters Flowchart Symbols USES Operator
281
Creating Procedures Large problems can be divided into smaller tasks to make them more manageable A procedure is the ASM equivalent of a Java or C++ function Following is an assembly language procedure named sample: sample PROC . ret sample ENDP
282
Documenting Procedures
Suggested documentation for each procedure: A description of all tasks accomplished by the procedure. Receives: A list of input parameters; state their usage and requirements. Returns: A description of values returned by the procedure. Requires: Optional list of requirements called preconditions that must be satisfied before the procedure is called. If a procedure is called without its preconditions having been satisfied, the procedure's creator makes no promise that it will work.
283
Example: SumOf Procedure
; SumOf PROC ; ; Calculates and returns the sum of three 32-bit integers. ; Receives: EAX, EBX, ECX, the three integers. May be ; signed or unsigned. ; Returns: EAX = sum, and the status flags (Carry, ; Overflow, etc.) are changed. ; Requires: nothing add eax,ebx add eax,ecx ret SumOf ENDP
284
CALL and RET Instructions
The CALL instruction calls a procedure pushes offset of next instruction on the stack copies the address of the called procedure into EIP The RET instruction returns from a procedure pops top of stack into EIP
285
CALL-RET Example (1 of 2) main PROC 00000020 call MySub
mov eax,ebx . main ENDP MySub PROC mov eax,edx ret MySub ENDP is the offset of the instruction immediately following the CALL instruction is the offset of the first instruction inside MySub
286
(stack shown before RET executes)
CALL-RET Example (2 of 2) The CALL instruction pushes onto the stack, and loads into EIP The RET instruction pops from the stack into EIP (stack shown before RET executes)
287
Nested Procedure Calls
By the time Sub3 is called, the stack contains all three return addresses:
288
Local and Global Labels
A local label is visible only to statements inside the same procedure. A global label is visible everywhere. main PROC jmp L2 ; error L1:: ; global label exit main ENDP sub2 PROC L2: ; local label jmp L1 ; ok ret sub2 ENDP
289
Procedure Parameters (1 of 3)
A good procedure might be usable in many different programs but not if it refers to specific variable names Parameters help to make procedures flexible because parameter values can change at runtime
290
Procedure Parameters (2 of 3)
The ArraySum procedure calculates the sum of an array. It makes two references to specific variable names: ArraySum PROC mov esi,0 ; array index mov eax,0 ; set the sum to zero L1: add eax,myArray[esi] ; add each integer to sum add esi,4 ; point to next integer loop L1 ; repeat for array size mov theSum,eax ; store the sum ret ArraySum ENDP What if you wanted to calculate the sum of two or three arrays within the same program?
291
Procedure Parameters (3 of 3)
This version of ArraySum returns the sum of any doubleword array whose address is in ESI. The sum is returned in EAX: ArraySum PROC ; Receives: ESI points to an array of doublewords, ; ECX = number of array elements. ; Returns: EAX = sum ; mov eax,0 ; set the sum to zero L1: add eax,[esi] ; add each integer to sum add esi,4 ; point to next integer loop L1 ; repeat for array size ret ArraySum ENDP
292
Flowchart Symbols The following symbols are the basic building blocks of flowcharts: (Includes two symbols not listed on page 166 of the book.)
293
Flowchart for the ArraySum Procedure
294
Your turn . . . Draw a flowchart that expresses the following pseudocode: input exam grade from the user if( grade > 70 ) display "Pass" else display "Fail" endif
295
. . . (Solution)
296
Your turn . . . Modify the flowchart in the previous slide to allow the user to continue to input exam scores until a value of –1 is entered
297
USES Operator Lists the registers that will be preserved
ArraySum PROC USES esi ecx mov eax,0 ; set the sum to zero etc. MASM generates the code shown in gold: ArraySum PROC push esi push ecx . pop ecx pop esi ret ArraySum ENDP
298
When not to push a register
The sum of the three registers is stored in EAX on line (3), but the POP instruction replaces it with the starting value of EAX on line (4): SumOf PROC ; sum of three integers push eax ; 1 add eax,ebx ; 2 add eax,ecx ; 3 pop eax ; 4 ret SumOf ENDP
299
Program Design Using Procedures
Top-Down Design (functional decomposition) involves the following: design your program before starting to code break large tasks into smaller ones use a hierarchical structure based on procedure calls test individual procedures separately
300
Integer Summation Program (1 of 4)
Description: Write a program that prompts the user for multiple 32-bit integers, stores them in an array, calculates the sum of the array, and displays the sum on the screen. Main steps: Prompt user for multiple integers Calculate the sum of the array Display the sum
301
Procedure Design (2 of 4) Main Clrscr ; clear screen PromptForIntegers
WriteString ; display string ReadInt ; input integer ArraySum ; sum the integers DisplaySum WriteInt ; display integer
302
gray indicates library procedure
Structure Chart (3 of 4) gray indicates library procedure View the stub program View the final program
303
Sample Output (4 of 4) Enter a signed integer: 550
The sum of the integers is: +431
304
Boolean and Comparison Instructions
CPU Status Flags AND Instruction OR Instruction XOR Instruction NOT Instruction Applications TEST Instruction CMP Instruction
305
Status Flags - Review The Zero flag is set when the result of an operation equals zero. The Carry flag is set when an instruction generates a result that is too large (or too small) for the destination operand. The Sign flag is set if the destination operand is negative, and it is clear if the destination operand is positive. The Overflow flag is set when an instruction generates an invalid signed result (bit 7 carry is XORed with bit 6 Carry). The Parity flag is set when an instruction generates an even number of 1 bits in the low byte of the destination operand. The Auxiliary Carry flag is set when an operation produces a carry out from bit 3 to bit 4
306
AND Instruction Performs a Boolean AND operation between each pair of matching bits in two operands Syntax: AND destination, source (same operand types as MOV) AND
307
AND / OR applications The AND instruction provides an easy way to translate a letter from lowcase to upercase . = 61h( ‘a’) = 41h (‘A’) If we AND any character with binary, all bits are unchanged except for bit 5, which is cleared The OR instruction always clears the Carry and Overflow flags . It modifies the Sign, Zero, and Parity flags according to the value of the destination operand Zero Flag Sign Flag Value in Al is .. clear Greater than zero set Equal to zero Less than zero
308
OR Instruction Performs a Boolean OR operation between each pair of matching bits in two operands Syntax: OR destination, source OR
309
XOR Instruction Performs a Boolean exclusive-OR operation between each pair of matching bits in two operands Syntax: XOR destination, source XOR XOR is a useful way to toggle (invert) the bits in an operand.
310
NOT Instruction Performs a Boolean NOT operation on a single destination operand Syntax: NOT destination NOT
311
AND/OR applications 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 OR forces selected bits to one Except for NOT these instructions affect the flags as follows: clear the carry (C) clear the overflow (0) 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 1’s) in the result scrambles the auxiliary carry flag (A) The NOT instruction does not affect any flags
312
Applications (1 of 5) Task: Convert the character in AL to upper case.
Solution: Use the AND instruction to clear bit 5. mov al,'a' ; AL = b and al, b ; AL = b
313
Applications (2 of 5) Task: Convert a binary decimal byte into its equivalent ASCII decimal digit. Solution: Use the OR instruction to set bits 4 and 5. mov al,6 ; AL = b or al, b ; AL = b The ASCII digit '6' = b
314
Applications (3 of 5) Task: Turn on the keyboard CapsLock key
Solution: Use the OR instruction to set bit 6 in the keyboard flag byte at 0040:0017h in the BIOS data area. mov ax,40h ; BIOS segment mov ds,ax mov bx,17h ; keyboard flag byte or BYTE PTR [bx], b ; CapsLock on This code only runs in Real-address mode, and it does not work under Windows NT, 2000, or XP.
315
Applications (4 of 5) Task: Jump to a label if an integer is even.
Solution: AND the lowest bit with a 1. If the result is Zero, the number was even. mov ax,wordVal and ax,1 ; low bit set? jz EvenValue ; jump if Zero flag set JZ (jump if Zero) is covered in Section 6.3. Your turn: Write code that jumps to a label if an integer is negative.
316
ORing any number with itself does not change its value.
Applications (5 of 5) Task: Jump to a label if the value in AL is not zero. Solution: OR the byte with itself, then use the JNZ (jump if not zero) instruction. or al,al jnz IsNotZero ; jump if not zero ORing any number with itself does not change its value.
317
TEST Instruction Performs a nondestructive AND operation between each pair of matching bits in two operands No operands are modified, but the Zero flag is affected. Example: jump to a label if either bit 0 or bit 1 in AL is set. test al, b jnz ValueFound Example: jump to a label if neither bit 0 nor bit 1 in AL is set. test al, b jz ValueNotFound
318
CMP Instruction (1 of 3) Example: destination < source
Compares the destination operand to the source operand Nondestructive subtraction of source from destination (destination operand is not changed) Syntax: CMP destination, source Example: destination == source mov al,5 cmp al,5 ; Zero flag set Example: destination < source mov al,4 cmp al,5 ; Carry flag set
319
CMP Instruction (2 of 3) Example: destination > source
mov al,6 cmp al,5 ; ZF = 0, CF = 0 (both the Zero and Carry flags are clear)
320
CMP Instruction (3 of 3) Example: destination > source
The comparisons shown here are performed with signed integers. Example: destination > source mov al,5 cmp al,-2 ; Sign flag == Overflow flag Example: destination < source mov al,-1 cmp al,5 ; Sign flag != Overflow flag
321
Conditional Jumps Jumps Based On . . . Applications
Specific flags Equality Unsigned comparisons Signed Comparisons Applications Encrypting a String Bit Test (BT) Instruction
322
Jcond Instruction A conditional jump instruction branches to a label when specific register or flag conditions are met Jcond destination Examples: JB, JC jump to a label if the Carry flag is set JE, JZ jump to a label if the Zero flag is set JS jumps to a label if the Sign flag is set JNE, JNZ jump to a label if the Zero flag is clear JECXZ jumps to a label if ECX equals 0
323
Jcond Instruction As explained earlier, the LOOP instruction decrements CX; if it is nonzero, control transfers to the operand address. You could replace the LOOP A20 statement with two statements – one that decrements CX and another that performs a conditional jump: DEC CX ; Equivalent to LOOP JNZ A20 DEC decrements CX by 1 and sets or clears the Zero Flag. JNZ then tests the setting of the Zero Flag; if CX is nonzero, control jumps to A20, and if CX is zero, control drops through to the next instructions. Just as for LOOP and JMP , the machine code operand for JNZ, contains the distance to the address of A20, which the operation adds to the IP register. For the 8086/286, the distance for a conditional jump must be short, within –128 to +127 bytes. The processors provide for 32-bit ( near) offsets that allow reaching any address within 32K
324
Jumps Based on Specific Flags
325
Jumps Based on Equality
CMP leftOp,rightOp
326
Jumps Based on Unsigned Comparisons
327
Jumps Based on Signed Comparisons
328
Applications (1 of 5) cmp eax,ebx ja Larger Task: Jump to a label if unsigned EAX is greater than EBX Solution: Use CMP, followed by JA cmp eax,ebx jg Greater Task: Jump to a label if signed EAX is greater than EBX Solution: Use CMP, followed by JG
329
Applications (2 of 5) cmp eax,Val1 jbe L1 ; below or equal Jump to label L1 if unsigned EAX is less than or equal to Val1 cmp eax,Val1 jle L1 Jump to label L1 if signed EAX is less than or equal to Val1
330
Applications (3 of 5) mov Large,bx cmp ax,bx jna Next mov Large,ax Next: Compare unsigned AX to BX, and copy the larger of the two into a variable named Large mov Small,ax cmp bx,ax jnl Next mov Small,bx Next: Compare signed AX to BX, and copy the smaller of the two into a variable named Small
331
Applications (4 of 5) Jump to label L1 if the memory word pointed to by ESI equals Zero cmp WORD PTR [esi],0 je L1 Jump to label L2 if the doubleword in memory pointed to by EDI is even test DWORD PTR [edi],1 jz L2
332
Applications (5 of 5) Task: Jump to label L1 if bits 0, 1, and 3 in AL are all set. Solution: Clear all bits except bits 0, 1,and 3. Then compare the result with binary. and al, b ; clear unwanted bits cmp al, b ; check remaining bits je L1 ; all set? jump to L1
333
Your turn . . . Write code that jumps to label L1 if either bit 4, 5, or 6 is set in the BL register. Write code that jumps to label L1 if bits 4, 5, and 6 are all set in the BL register. Write code that jumps to label L2 if AL has even parity. Write code that jumps to label L3 if EAX is negative. Write code that jumps to label L4 if the expression (EBX – ECX) is greater than zero.
334
Encrypting a String The following loop uses the XOR instruction to transform every character in a string into a new value. KEY = 239 ; can be any byte value BUFMAX = 128 .data buffer BYTE BUFMAX+1 DUP(0) bufSize DWORD BUFMAX .code mov ecx,bufSize ; loop counter mov esi,0 ; index 0 in buffer L1: xor buffer[esi],KEY ; translate a byte inc esi ; point to next byte loop L1
335
String Encryption Program
Tasks: Input a message (string) from the user Encrypt the message Display the encrypted message Decrypt the message Display the decrypted message
336
BT (Bit Test) Instruction
Copies bit n from an operand into the Carry flag Syntax: BT bitBase, n bitBase may be r/m16 or r/m32 n may be r16, r32, or imm8 Example: jump to label L1 if bit 9 is set in the AX register: bt AX,9 ; CF = bit 9 jc L1 ; jump if Carry
337
Conditional Loop Instructions
LOOPZ and LOOPE LOOPNZ and LOOPNE
338
LOOPZ and LOOPE Syntax: Logic:
LOOPE destination LOOPZ destination Logic: ECX ECX – 1 if ECX > 0 and ZF=1, jump to destination Useful when scanning an array for the first element that does not match a given value.
339
LOOPNZ and LOOPNE LOOPNZ (LOOPNE) is a conditional loop instruction
Syntax: LOOPNZ destination LOOPNE destination Logic: ECX ECX – 1; if ECX > 0 and ZF=0, jump to destination Useful when scanning an array for the first element that matches a given value.
340
LOOPNZ Example The following code finds the first positive value in an array: .data array SWORD -3,-6,-1,-10,10,30,40,4 sentinel SWORD 0 .code mov esi,OFFSET array mov ecx,LENGTHOF array next: test WORD PTR [esi],8000h ; test sign bit pushfd ; push flags on stack add esi,TYPE array popfd ; pop flags from stack loopnz next ; continue loop jnz quit ; none found sub esi,TYPE array ; ESI points to value quit:
341
Your turn . . . Locate the first nonzero value in the array. If none is found, let ESI point to the sentinel value: .data array SWORD 50 DUP(?) sentinel SWORD 0FFFFh .code mov esi,OFFSET array mov ecx,LENGTHOF array L1: cmp WORD PTR [esi],0 ; check for zero (fill in your code here) quit:
342
. . . (solution) .data array SWORD 50 DUP(?) sentinel SWORD 0FFFFh
.code mov esi,OFFSET array mov ecx,LENGTHOF array L1: cmp WORD PTR [esi],0 ; check for zero pushfd ; push flags on stack add esi,TYPE array popfd ; pop flags from stack loope next ; continue loop jz quit ; none found sub esi,TYPE array ; ESI points to value quit:
343
Conditional Structures
Block-Structured IF Statements Compound Expressions with AND Compound Expressions with OR WHILE Loops Table-Driven Selection
344
Block-Structured IF Statements
Assembly language programmers can easily translate logical statements written in C++/Java into assembly language. For example: mov eax,op1 cmp eax,op2 jne L1 mov X,1 jmp L2 L1: mov X,2 L2: if( op1 == op2 ) X = 1; else X = 2;
345
(There are multiple correct solutions to this problem.)
Your turn . . . Implement the following pseudocode in assembly language. All values are unsigned: if( ebx <= ecx ) { eax = 5; edx = 6; } cmp ebx,ecx ja next mov eax,5 mov edx,6 next: (There are multiple correct solutions to this problem.)
346
(There are multiple correct solutions to this problem.)
Your turn . . . Implement the following pseudocode in assembly language. All values are 32-bit signed integers: if( var1 <= var2 ) var3 = 10; else { var3 = 6; var4 = 7; } mov eax,var1 cmp eax,var2 jle L1 mov var3,6 mov var4,7 jmp L2 L1: mov var3,10 L2: (There are multiple correct solutions to this problem.)
347
Compound Expression with AND (1 of 3)
When implementing the logical AND operator, consider that HLLs use short-circuit evaluation In the following example, if the first expression is false, the second expression is skipped: if (al > bl) AND (bl > cl) X = 1;
348
Compound Expression with AND (2 of 3)
if (al > bl) AND (bl > cl) X = 1; This is one possible implementation . . . cmp al,bl ; first expression... ja L1 jmp next L1: cmp bl,cl ; second expression... ja L2 L2: ; both are true mov X,1 ; set X to 1 next:
349
Compound Expression with AND (3 of 3)
if (al > bl) AND (bl > cl) X = 1; But the following implementation uses 29% less code by reversing the first relational operator. We allow the program to "fall through" to the second expression: cmp al,bl ; first expression... jbe next ; quit if false cmp bl,cl ; second expression... mov X,1 ; both are true next:
350
(There are multiple correct solutions to this problem.)
Your turn . . . Implement the following pseudocode in assembly language. All values are unsigned: if( ebx <= ecx && ecx > edx ) { eax = 5; edx = 6; } cmp ebx,ecx ja next cmp ecx,edx jbe next mov eax,5 mov edx,6 next: (There are multiple correct solutions to this problem.)
351
Compound Expression with OR (1 of 2)
When implementing the logical OR operator, consider that HLLs use short-circuit evaluation In the following example, if the first expression is true, the second expression is skipped: if (al > bl) OR (bl > cl) X = 1;
352
Compound Expression with OR (1 of 2)
if (al > bl) OR (bl > cl) X = 1; We can use "fall-through" logic to keep the code as short as possible: cmp al,bl ; is AL > BL? ja L1 ; yes cmp bl,cl ; no: is BL > CL? jbe next ; no: skip next statement L1: mov X,1 ; set X to 1 next:
353
WHILE Loops A WHILE loop is really an IF statement followed by the body of the loop, followed by an unconditional jump to the top of the loop. Consider the following example: while( eax < ebx) eax = eax + 1; top: cmp eax,ebx ; check loop condition jae next ; false? exit loop inc eax ; body of loop jmp top ; repeat the loop next: This is a possible implementation:
354
Your turn . . . Implement the following loop, using unsigned 32-bit integers: while( ebx <= val1) { ebx = ebx + 5; val1 = val1 - 1 } top: cmp ebx,val1 ; check loop condition ja next ; false? exit loop add ebx,5 ; body of loop dec val1 jmp top ; repeat the loop next:
355
Table-Driven Selection (1 of 3)
Table-driven selection uses a table lookup to replace a multiway selection structure Create a table containing lookup values and the offsets of labels or procedures Use a loop to search the table Suited to a large number of comparisons
356
Table-Driven Selection (2 of 3)
Step 1: create a table containing lookup values and procedure offsets: .data CaseTable BYTE 'A' ; lookup value DWORD Process_A ; address of procedure EntrySize = ($ - CaseTable) BYTE 'B' DWORD Process_B BYTE 'C' DWORD Process_C BYTE 'D' DWORD Process_D NumberOfEntries = ($ - CaseTable) / EntrySize
357
Table-Driven Selection (3 of 3)
Step 2: Use a loop to search the table. When a match is found, we call the procedure offset stored in the current table entry: mov ebx,OFFSET CaseTable ; point EBX to the table mov ecx,NumberOfEntries ; loop counter L1: cmp al,[ebx] ; match found? jne L2 ; no: continue call NEAR PTR [ebx + 1] ; yes: call the procedure jmp L3 ; and exit the loop L2: add ebx,EntrySize ; point to next entry loop L1 ; repeat until ECX = 0 L3: required for procedure pointers
358
Application: Finite-State Machines
A finite-state machine (FSM) is a graph structure that changes state based on some input. Also called a state-transition diagram. We use a graph to represent an FSM, with squares or circles called nodes, and lines with arrows between the circles called edges (or arcs). A FSM is a specific instance of a more general structure called a directed graph (or digraph). Three basic states, represented by nodes: Start state Terminal state(s) Nonterminal state(s)
359
Finite-State Machine Accepts any sequence of symbols that puts it into an accepting (final) state Can be used to recognize, or validate a sequence of characters that is governed by language rules (called a regular expression) Advantages: Provides visual tracking of program's flow of control Easy to modify Easily implemented in assembly language
360
FSM Examples FSM that recognizes strings beginning with 'x', followed by letters 'a'..'y', ending with 'z': FSM that recognizes signed integers:
361
Your turn . . . Explain why the following FSM does not work as well for signed integers as the one shown on the previous slide:
362
Implementing an FSM The following is code from State A in the Integer FSM: StateA: call Getnext ; read next char into AL cmp al,'+' ; leading + sign? je StateB ; go to State B cmp al,'-' ; leading - sign? call IsDigit ; ZF = 1 if AL = digit jz StateC ; go to State C call DisplayErrorMsg ; invalid input found jmp Quit View the Finite.asm source code.
363
IsDigit Procedure Receives a character in AL. Sets the Zero flag if the character is a decimal digit. IsDigit PROC cmp al,'0' ; ZF = 0 jb ID1 cmp al,'9' ; ZF = 0 ja ID1 test ax, ; ZF = 1 ID1: ret IsDigit ENDP
364
Flowchart of State A State A accepts a plus or minus sign, or a decimal digit.
365
Your turn . . . Draw a FSM diagram for hexadecimal integer constant that conforms to MASM syntax. Draw a flowchart for one of the states in your FSM. Implement your FSM in assembly language. Let the user input a hexadecimal constant from the keyboard.
366
Using the .IF Directive Runtime Expressions
Relational and Logical Operators MASM-Generated Code .REPEAT Directive .WHILE Directive
367
Runtime Expressions .IF, .ELSE, .ELSEIF, and .ENDIF can be used to evaluate runtime expressions and create block-structured IF statements. Examples: .IF eax > ebx mov edx,1 .ELSE mov edx,2 .ENDIF .IF eax > ebx && eax > ecx mov edx,1 .ELSE mov edx,2 .ENDIF MASM generates "hidden" code for you, consisting of code labels, CMP and conditional jump instructions.
368
Relational and Logical Operators
369
MASM-Generated Code Generated code:
.data val1 DWORD 5 result DWORD ? .code mov eax,6 .IF eax > val1 mov result,1 .ENDIF Generated code: mov eax,6 cmp eax,val1 mov result,1 @C0001: MASM automatically generates an unsigned jump (JBE) because val1 is unsigned.
370
MASM-Generated Code Generated code:
.data val1 SDWORD 5 result SDWORD ? .code mov eax,6 .IF eax > val1 mov result,1 .ENDIF Generated code: mov eax,6 cmp eax,val1 mov result,1 @C0001: MASM automatically generates a signed jump (JLE) because val1 is signed.
371
MASM-Generated Code Generated code:
.data result DWORD ? .code mov ebx,5 mov eax,6 .IF eax > ebx mov result,1 .ENDIF Generated code: mov ebx,5 mov eax,6 cmp eax,ebx mov result,1 @C0001: MASM automatically generates an unsigned jump (JBE) when both operands are registers . . .
372
MASM-Generated Code Generated code:
.data result SDWORD ? .code mov ebx,5 mov eax,6 .IF SDWORD PTR eax > ebx mov result,1 .ENDIF Generated code: mov ebx,5 mov eax,6 cmp eax,ebx mov result,1 @C0001: . . . unless you prefix one of the register operands with the SDWORD PTR operator. Then a signed jump is generated.
373
.REPEAT Directive Executes the loop body before testing the loop condition associated with the .UNTIL directive. Example: ; Display integers 1 – 10: mov eax,0 .REPEAT inc eax call WriteDec call Crlf .UNTIL eax == 10
374
.WHILE Directive Tests the loop condition before executing the loop body The .ENDW directive marks the end of the loop. Example: ; Display integers 1 – 10: mov eax,0 .WHILE eax < 10 inc eax call WriteDec call Crlf .ENDW
375
Shift and Rotate Instructions
Logical vs Arithmetic Shifts SHL Instruction SHR Instruction SAL and SAR Instructions ROL Instruction ROR Instruction RCL and RCR Instructions SHLD/SHRD Instructions
376
Logical vs Arithmetic Shifts
A logical shift fills the newly created bit position with zero: An arithmetic shift fills the newly created bit position with a copy of the number’s sign bit:
377
SHL Instruction The SHL (shift left) instruction performs a logical left shift on the destination operand, filling the lowest bit with 0. Operand types for SHL: SHL reg,imm8 SHL mem,imm8 SHL reg,CL SHL mem,CL (Same for all shift and rotate instructions)
378
Fast Multiplication Shifting left 1 bit multiplies a number by 2
mov dl,5 shl dl,1 mov dl,5 shl dl,2 ; DL = 20 Shifting left n bits multiplies the operand by 2n For example, 5 * 22 = 20
379
SHR Instruction The SHR (shift right) instruction performs a logical right shift on the destination operand. The highest bit position is filled with a zero. mov dl,80 shr dl,1 ; DL = 40 shr dl,2 ; DL = 10 Shifting right n bits divides the operand by 2n
380
SAL and SAR Instructions
SAL (shift arithmetic left) is identical to SHL. SAR (shift arithmetic right) performs a right arithmetic shift on the destination operand. An arithmetic shift preserves the number's sign. mov dl,-80 sar dl,1 ; DL = -40 sar dl,2 ; DL = -10
381
Your turn . . . Indicate the hexadecimal value of AL after each shift:
mov al,6Bh shr al,1 a. shl al,3 b. mov al,8Ch sar al,1 c. sar al,3 d. 35h A8h C6h F8h
382
ROL Instruction ROL (rotate) shifts each bit to the left
The highest bit is copied into both the Carry flag and into the lowest bit No bits are lost mov al, b rol al,1 ; AL = b mov dl,3Fh rol dl,4 ; DL = F3h
383
ROR Instruction ROR (rotate right) shifts each bit to the right
The lowest bit is copied into both the Carry flag and into the highest bit No bits are lost mov al, b ror al,1 ; AL = b mov dl,3Fh ror dl,4 ; DL = F3h
384
Your turn . . . Indicate the hexadecimal value of AL after each rotation: mov al,6Bh ror al,1 a. rol al,3 b. B5h ADh
385
RCL Instruction RCL (rotate carry left) shifts each bit to the left
Copies the Carry flag to the least significant bit Copies the most significant bit to the Carry flag clc ; CF = 0 mov bl,88h ; CF,BL = b rcl bl,1 ; CF,BL = b rcl bl,1 ; CF,BL = b
386
RCR Instruction RCR (rotate carry right) shifts each bit to the right
Copies the Carry flag to the most significant bit Copies the least significant bit to the Carry flag stc ; CF = 1 mov ah,10h ; CF,AH = b rcr ah,1 ; CF,AH = b
387
Your turn . . . Indicate the hexadecimal value of AL after each rotation: stc mov al,6Bh rcr al,1 a. rcl al,3 b. B5h AEh
388
SHLD Instruction Shifts a destination operand a given number of bits to the left The bit positions opened up by the shift are filled by the most significant bits of the source operand The source operand is not affected Syntax: SHLD destination, source, count Operand types: SHLD reg16/32, reg16/32, imm8/CL SHLD mem16/32, reg16/32, imm8/CL
389
SHLD Example Shift wval 4 bits to the left and replace its lowest 4 bits with the high 4 bits of AX: .data wval WORD 9BA6h .code mov ax,0AC36h shld wval,ax,4 Before: After:
390
SHRD Instruction Shifts a destination operand a given number of bits to the right The bit positions opened up by the shift are filled by the least significant bits of the source operand The source operand is not affected Syntax: SHRD destination, source, count Operand types: SHRD reg16/32, reg16/32, imm8/CL SHRD mem16/32, reg16/32, imm8/CL
391
SHRD Example Shift AX 4 bits to the right and replace its highest 4 bits with the low 4 bits of DX: mov ax,234Bh mov dx,7654h shrd ax,dx,4 Before: After:
392
Your turn . . . Indicate the hexadecimal values of each destination operand: mov ax,7C36h mov dx,9FA6h shld dx,ax,4 ; DX = shrd dx,ax,8 ; DX = FA67h 36FAh
393
Shift and Rotate Applications
Shifting Multiple Doublewords Binary Multiplication Displaying Binary Bits Isolating a Bit String
394
Shifting Multiple Doublewords
Programs sometimes need to shift all bits within an array, as one might when moving a bitmapped graphic image from one screen location to another. The following shifts an array of 3 doublewords 1 bit to the right (view complete source code): .data ArraySize = 3 array DWORD ArraySize DUP( h) ; .code mov esi,0 shr array[esi + 8],1 ; high dword rcr array[esi + 4],1 ; middle dword, include Carry rcr array[esi],1 ; low dword, include Carry
395
Binary Multiplication
We already know that SHL performs unsigned multiplication efficiently when the multiplier is a power of 2. You can factor any binary number into powers of 2. For example, to multiply EAX * 36, factor 36 into and use the distributive property of multiplication to carry out the operation: EAX * 36 = EAX * (32 + 4) = (EAX * 32)+(EAX * 4) mov eax,123 mov ebx,eax shl eax,5 ; mult by 25 shl ebx,2 ; mult by 22 add eax,ebx
396
Your turn . . . Multiply AX by 26, using shifting and addition instructions. Hint: 26 = mov ax,2 ; test value mov dx,ax shl dx,4 ; AX * 16 push dx ; save for later shl dx,3 ; AX * 8 shl ax,1 ; AX * 2 add ax,dx ; AX * 10 pop dx ; recall AX * 16 add ax,dx ; AX * 26
397
Displaying Binary Bits
Algorithm: Shift MSB into the Carry flag; If CF = 1, append a "1" character to a string; otherwise, append a "0" character. Repeat in a loop, 32 times. .data buffer BYTE 32 DUP(0),0 .code mov ecx,32 mov esi,OFFSET buffer L1: shl eax,1 mov BYTE PTR [esi],'0' jnc L2 mov BYTE PTR [esi],'1' L2: inc esi loop L1
398
Isolating a Bit String The MS-DOS file date field packs the year, month, and day into 16 bits: mov ax,dx ; make a copy of DX shr ax,5 ; shift right 5 bits and al, b ; clear bits 4-7 mov month,al ; save in month variable Isolate the Month field:
399
Multiplication and Division Instructions
MUL Instruction IMUL Instruction DIV Instruction Signed Integer Division CBW, CWD, CDQ Instructions IDIV Instruction Implementing Arithmetic Expressions
400
MUL Instruction The MUL (unsigned multiply) instruction multiplies an 8-, 16-, or 32-bit operand by either AL, AX, or EAX. The instruction formats are: MUL r/m8 MUL r/m16 MUL r/m32 Implied operands:
401
MUL Examples 100h * 2000h, using 16-bit operands:
.data val1 WORD 2000h val2 WORD 100h .code mov ax,val1 mul val2 ; DX:AX = h, CF=1 The Carry flag indicates whether or not the upper half of the product contains significant digits. mov eax,12345h mov ebx,1000h mul ebx ; EDX:EAX = h, CF=0 12345h * 1000h, using 32-bit operands:
402
Your turn . . . What will be the hexadecimal values of DX, AX, and the Carry flag after the following instructions execute? mov ax,1234h mov bx,100h mul bx DX = 0012h, AX = 3400h, CF = 1
403
Your turn . . . What will be the hexadecimal values of EDX, EAX, and the Carry flag after the following instructions execute? mov eax, h mov ecx,10000h mul ecx EDX = h, EAX = h, CF = 1
404
IMUL Instruction IMUL (signed integer multiply ) multiplies an 8-, 16-, or 32-bit signed operand by either AL, AX, or EAX Preserves the sign of the product by sign-extending it into the upper half of the destination register Example: multiply 48 * 4, using 8-bit operands: mov al,48 mov bl,4 imul bl ; AX = 00C0h, OF=1 OF=1 because AH is not a sign extension of AL.
405
IMUL Examples Multiply 4,823,424 * -423:
mov eax, mov ebx,-423 imul ebx ; EDX:EAX = FFFFFFFF86635D80h, OF=0 OF=0 because EDX is a sign extension of EAX.
406
Your turn . . . What will be the hexadecimal values of DX, AX, and the Carry flag after the following instructions execute? mov ax,8760h mov bx,100h imul bx DX = FF87h, AX = 6000h, OF = 1
407
DIV Instruction The DIV (unsigned divide) instruction performs 8-bit, 16-bit, and 32-bit division on unsigned integers A single operand is supplied (register or memory operand), which is assumed to be the divisor Instruction formats: DIV r/m8 DIV r/m16 DIV r/m32 Default Operands:
408
DIV Examples Divide 8003h by 100h, using 16-bit operands:
mov dx,0 ; clear dividend, high mov ax,8003h ; dividend, low mov cx,100h ; divisor div cx ; AX = 0080h, DX = 3 Same division, using 32-bit operands: mov edx,0 ; clear dividend, high mov eax,8003h ; dividend, low mov ecx,100h ; divisor div ecx ; EAX = h, DX = 3
409
Your turn . . . What will be the hexadecimal values of DX and AX after the following instructions execute? Or, if divide overflow occurs, you can indicate that as your answer: mov dx,0087h mov ax,6000h mov bx,100h div bx DX = 0000h, AX = 8760h
410
Your turn . . . What will be the hexadecimal values of DX and AX after the following instructions execute? Or, if divide overflow occurs, you can indicate that as your answer: mov dx,0087h mov ax,6002h mov bx,10h div bx Divide Overflow
411
Signed Integer Division
Signed integers must be sign-extended before division takes place fill high byte/word/doubleword with a copy of the low byte/word/doubleword's sign bit For example, the high byte contains a copy of the sign bit from the low byte:
412
CBW, CWD, CDQ Instructions
The CBW, CWD, and CDQ instructions provide important sign-extension operations: CBW (convert byte to word) extends AL into AH CWD (convert word to doubleword) extends AX into DX CDQ (convert doubleword to quadword) extends EAX into EDX Example: mov eax,0FFFFFF9Bh ; (-101) cdq ; EDX:EAX = FFFFFFFFFFFFFF9Bh Your copy of the book may have an error on page 243: 9Bh equals –101 rather than –65.
413
IDIV Instruction IDIV (signed divide) performs signed integer division
Same syntax and operands as DIV instruction Example: 8-bit division of –48 by 5 mov al,-48 cbw ; extend AL into AH mov bl,5 idiv bl ; AL = -9, AH = -3
414
IDIV Examples Example: 16-bit division of –48 by 5
mov ax,-48 cwd ; extend AX into DX mov bx,5 idiv bx ; AX = -9, DX = -3 Example: 32-bit division of –48 by 5 mov eax,-48 cdq ; extend EAX into EDX mov ebx,5 idiv ebx ; EAX = -9, EDX = -3
415
Your turn . . . What will be the hexadecimal values of DX and AX after the following instructions execute? Or, if divide overflow occurs, you can indicate that as your answer: mov ax,0FDFFh ; -513 cwd mov bx,100h idiv bx DX = FFFFh (-1), AX = FFFEh (-2)
416
Unsigned Arithmetic Expressions
Some good reasons to learn how to implement integer expressions: Learn how do compilers do it Test your understanding of MUL, IMUL, DIV, IDIV Check for overflow (Carry and Overflow flags) Example: var4 = (var1 + var2) * var3 ; Assume unsigned operands mov eax,var1 add eax,var2 ; EAX = var1 + var2 mul var3 ; EAX = EAX * var3 jc TooBig ; check for carry mov var4,eax ; save product
417
Signed Arithmetic Expressions (1 of 2)
Example: eax = (-var1 * var2) + var3 mov eax,var1 neg eax imul var2 jo TooBig ; check for overflow add eax,var3 Example: var4 = (var1 * 5) / (var2 – 3) mov eax,var1 ; left side mov ebx,5 imul ebx ; EDX:EAX = product mov ebx,var2 ; right side sub ebx,3 idiv ebx ; EAX = quotient mov var4,eax
418
Signed Arithmetic Expressions (2 of 2)
Example: var4 = (var1 * -5) / (-var2 % var3); mov eax,var2 ; begin right side neg eax cdq ; sign-extend dividend idiv var3 ; EDX = remainder mov ebx,edx ; EBX = right side mov eax,-5 ; begin left side imul var1 ; EDX:EAX = left side idiv ebx ; final division mov var4,eax ; quotient Sometimes it's easiest to calculate the right-hand term of an expression first.
419
Your turn . . . Implement the following expression using signed 32-bit integers: eax = (ebx * 20) / ecx mov eax,20 imul ebx idiv ecx
420
Your turn . . . Implement the following expression using signed 32-bit integers. Save and restore ECX and EDX: eax = (ecx * edx) / eax push edx push eax ; EAX needed later mov eax,ecx imul edx ; left side: EDX:EAX pop ebx ; saved value of EAX idiv ebx ; EAX = quotient pop edx ; restore EDX, ECX
421
Your turn . . . Implement the following expression using signed 32-bit integers. Do not modify any variables other than var3: var3 = (var1 * -var2) / (var3 – ebx) mov eax,var1 mov edx,var2 neg edx imul edx ; left side: EDX:EAX mov ecx,var3 sub ecx,ebx idiv ecx ; EAX = quotient mov var3,eax
422
Extended Precision Arithmetic
ADC Instruction Extended Precision Addition SBB Instruction Extended Precision Subtraction
423
Extended Precision Addition
Adding two operands that are longer than the computer's word size (32 bits). Virtually no limit to the size of the operands The arithmetic must be performed in steps The Carry value from each step is passed on to the next step.
424
ADC Instruction ADC (add with carry) instruction adds both a source operand and the contents of the Carry flag to a destination operand. Operands are binary values Same syntax as ADD, SUB, etc. Example Add two 32-bit integers (FFFFFFFFh + FFFFFFFFh), producing a 64-bit sum in EDX:EAX: mov edx,0 mov eax,0FFFFFFFFh add eax,0FFFFFFFFh adc edx,0 ;EDX:EAX = FFFFFFFEh
425
Extended Addition Example
Task: Add 1 to EDX:EAX Starting value of EDX:EAX: FFFFFFFFh Add the lower 32 bits first, setting the Carry flag. Add the upper 32 bits, and include the Carry flag. mov edx,0 ; set upper half mov eax,0FFFFFFFFh ; set lower half add eax,1 ; add lower half adc edx,0 ; add upper half EDX:EAX =
426
SBB Instruction The SBB (subtract with borrow) instruction subtracts both a source operand and the value of the Carry flag from a destination operand. Operand syntax: Same as for the ADC instruction
427
Extended Subtraction Example
Task: Subtract 1 from EDX:EAX Starting value of EDX:EAX: h Subtract the lower 32 bits first, setting the Carry flag. Subtract the upper 32 bits, and include the Carry flag. mov edx,1 ; set upper half mov eax,0 ; set lower half sub eax,1 ; subtract lower half sbb edx,0 ; subtract upper half EDX:EAX = FFFFFFFF
428
ASCII and Packed Decimal Arithmetic
Binary Coded Decimal ASCII Decimal AAA Instruction AAS Instruction AAM Instruction AAD Instruction Packed Decimal Integers DAA Instruction DAS Instruction
429
Binary-Coded Decimal Binary-coded decimal (BCD) integers use 4 binary bits to represent each decimal digit A number using unpacked BCD representation stores a decimal digit in the lower four bits of each byte For example, 5,678 is stored as the following sequence of hexadecimal bytes: 05 06 07 08
430
ASCII Decimal A number using ASCII Decimal representation stores a single ASCII digit in each byte For example, 5,678 is stored as the following sequence of hexadecimal bytes: 35 36 37 38
431
AAA Instruction The AAA (ASCII adjust after addition) instruction adjusts the binary result of an ADD or ADC instruction. It makes the result in AL consistent with ASCII decimal representation. The Carry value, if any ends up in AH Example: Add '8' and '2' mov ah,0 mov al,'8' ; AX = 0038h add al,'2' ; AX = 006Ah aaa ; AX = 0100h (adjust result) or ax,3030h ; AX = 3130h = '10'
432
AAS Instruction The AAS (ASCII adjust after subtraction) instruction adjusts the binary result of an SUB or SBB instruction. It makes the result in AL consistent with ASCII decimal representation. It places the Carry value, if any, in AH Example: Subtract '9' from '8' mov ah,0 mov al,'8' ; AX = 0038h sub al,'9' ; AX = 00FFh aas ; AX = FF09h, CF=1 or al,30h ; AL = '9'
433
AAM Instruction The AAM (ASCII adjust after multiplication) instruction adjusts the binary result of a MUL instruction. The multiplication must have been performed on unpacked BCD numbers. mov bl,05h ; first operand mov al,06h ; second operand mul bl ; AX = 001Eh aam ; AX = 0300h
434
AAD Instruction The AAD (ASCII adjust before division) instruction adjusts the unpacked BCD dividend in AX before a division operation .data quotient BYTE ? remainder BYTE ? .code mov ax,0307h ; dividend aad ; AX = 0025h mov bl,5 ; divisor div bl ; AX = 0207h mov quotient,al mov remainder,ah
435
Packed Decimal Integers
Packed decimal stores two decimal digits per byte For example, 12,345,678 can be stored as the following sequence of hexadecimal bytes: 12 34 56 78 Packed decimal is also known as packed BCD. There is no limit on the number of bytes you can use to store a packed decimal number. Financial values are frequently stored in this format to permit high precision when performing calculations.
436
DAA Instruction The DAA (decimal adjust after addition) instruction converts the binary result of an ADD or ADC operation to packed decimal format. The value to be adjusted must be in AL If the lower digit is adjusted, the Auxiliary Carry flag is set. If the upper digit is adjusted, the Carry flag is set.
437
DAA Logic If (AL(lo) > 9) or (AuxCarry = 1) AL = AL + 6
Else AuxCarry = 0 Endif If (AL(hi) > 9) or Carry = 1 AL = AL + 60h Carry = 1 Carry = 0 If AL = AL + 6 sets the Carry flag, its value is used when evaluating AL(hi).
438
DAA Examples Example: calculate BCD 35 + 48
mov al,35h add al,48h ; AL = 7Dh daa ; AL = 83h, CF = 0 Example: calculate BCD mov al,35h add al,65h ; AL = 9Ah daa ; AL = 00h, CF = 1 Example: calculate BCD mov al,69h add al,29h ; AL = 92h daa ; AL = 98h, CF = 0
439
Your turn . . . A temporary malfunction in your computer's processor has disabled the DAA instruction. Write a procedure in assembly language that performs the same actions as DAA. Test your procedure using the values from the previous slide.
440
DAS Instruction The DAS (decimal adjust after subtraction) instruction converts the binary result of a SUB or SBB operation to packed decimal format. The value must be in AL Example: subtract BCD 48 from 85 mov al,48h sub al,35h ; AL = 13h das ; AL = 13h CF = 0
441
DAS Logic If (AL(lo) > 9) OR (AuxCarry = 1) AL = AL − 6; AuxCarry = 1; Else AuxCarry = 0; Endif If (AL > 9FH) or (Carry = 1) AL = AL − 60h; Carry = 1; Carry = 0; If AL = AL - 6 sets the Carry flag, its value is used when evaluating AL in the second IF statement.
442
DAS Examples (1 of 2) Example: subtract BCD 48 – 35
mov al,48h sub al,35h ; AL = 13h das ; AL = 13h CF = 0 Example: subtract BCD 62 – 35 mov al,62h sub al,35h ; AL = 2Dh, CF = 0 das ; AL = 27h, CF = 0 Example: subtract BCD 32 – 29 mov al,32h add al,29h ; AL = 09h, CF = 0 daa ; AL = 03h, CF = 0
443
DAS Examples (2 of 2) Example: subtract BCD 32 – 39 mov al,32h
sub al,39h ; AL = F9h, CF = 1 das ; AL = 93h, CF = 1 Steps: AL = F9h CF = 1, so subtract 6 from F9h AL = F3h F3h > 9Fh, so subtract 60h from F3h AL = 93h, CF = 1
444
Your turn . . . A temporary malfunction in your computer's processor has disabled the DAS instruction. Write a procedure in assembly language that performs the same actions as DAS. Test your procedure using the values from the previous two slides.
445
Assembly Language for Intel-Based Computers, 4th Edition
Kip R. Irvine Chapter 8:Advanced Procedures Slides prepared by Kip R. Irvine Revision date: 11/04/2002 Chapter corrections (Web) Assembly language sources (Web) (c) Pearson Education, All rights reserved. You may modify and copy this slide show for your personal use, or for use in the classroom, as long as this copyright statement, the author's name, and the title are not changed.
446
Chapter Overview Local Variables Stack Parameters Stack Frames
Recursion Creating Multimodule Programs
447
Local Directive A local variable is created, used, and destroyed within a single procedure The LOCAL directive declares a list of local variables immediately follows the PROC directive each variable is assigned a type Syntax: LOCAL varlist Example: MySub PROC LOCAL var1:BYTE, var2:WORD, var3:SDWORD
448
Local Variables Examples: LOCAL flagVals[20]:BYTE ; array of bytes
LOCAL pArray:PTR WORD ; pointer to an array myProc PROC, ; procedure p1:PTR WORD ; parameter LOCAL t1:BYTE, ; local variables t2:WORD, t3:DWORD, t4:PTR DWORD
449
MASM-Generated Code (1 of 2)
BubbleSort PROC LOCAL temp:DWORD, SwapFlag:BYTE . . . ret BubbleSort ENDP MASM generates the following code: BubbleSort PROC push ebp mov ebp,esp add esp,0FFFFFFF8h ; add -8 to ESP . . . mov esp,ebp pop ebp ret BubbleSort ENDP
450
MASM-Generated Code (2 of 2)
Diagram of the stack frame for the BubbleSort procedure:
451
Stack Parameters Register vs. Stack Parameters INVOKE Directive
PROC Directive PROTO Directive Passing by Value or by Reference Parameter Classifications Example: Exchanging Two Integers Trouble-Shooting Tips
452
Register vs. Stack Parameters
Register parameters require dedicating a register to each parameter. Stack parameters are more convenient Imagine two possible ways of calling the DumpMem procedure. Clearly the second is easier: push OFFSET array push LENGTHOF array push TYPE array call DumpMem pushad mov esi,OFFSET array mov ecx,LENGTHOF array mov ebx,TYPE array call DumpMem popad
453
INVOKE Directive The INVOKE directive is a powerful replacement for Intel’s CALL instruction that lets you pass multiple arguments Syntax: INVOKE procedureName [, argumentList] ArgumentList is an optional comma-delimited list of procedure arguments Arguments can be: immediate values and integer expressions variable names address and ADDR expressions register names
454
INVOKE Examples .data byteVal BYTE 10 wordVal WORD 1000h .code
; direct operands: INVOKE Sub1,byteVal,wordVal ; address of variable: INVOKE Sub2,ADDR byteVal ; register name, integer expression: INVOKE Sub3,eax,(10 * 20) ; address expression (indirect operand): INVOKE Sub4,[ebx]
455
ADDR Operator Returns a near or far pointer to a variable, depending on which memory model your program uses: Small model: returns 16-bit offset Large model: returns 32-bit segment/offset Flat model: returns 32-bit offset Simple example: .data myWord WORD ? .code INVOKE mySub,ADDR myWord
456
PROC Directive (1 of 2) The PROC directive declares a procedure with an optional list of named parameters. Syntax: label PROC paramList paramList is a list of parameters separated by commas. Each parameter has the following syntax: paramName : type type must either be one of the standard ASM types (BYTE, SBYTE, WORD, etc.), or it can be a pointer to one of these types.
457
PROC Directive (2 of 2) Alternate format permits parameter list to be on one or more separate lines: label PROC, paramList The parameters can be on the same line . . . param-1:type-1, param-2:type-2, . . ., param-n:type-n Or they can be on separate lines: param-1:type-1, param-2:type-2, . . ., param-n:type-n comma required
458
AddTwo Procedure (1 of 2) The AddTwo procedure receives two integers and returns their sum in EAX. AddTwo PROC, val1:DWORD, val2:DWORD mov eax,val1 add eax,val2 ret AddTwo ENDP
459
PROC Examples (2 of 3) FillArray receives a pointer to an array of bytes, a single byte fill value that will be copied to each element of the array, and the size of the array. FillArray PROC, pArray:PTR BYTE, fillVal:BYTE arraySize:DWORD mov ecx,arraySize mov esi,pArray mov al,fillVal L1: mov [esi],al inc esi loop L1 ret FillArray ENDP
460
PROC Examples (3 of 3) Swap PROC, pValX:PTR DWORD, pValY:PTR DWORD
. . . Swap ENDP ReadFile PROC, pBuffer:PTR BYTE LOCAL fileHandle:DWORD . . . ReadFile ENDP
461
RET Instruction Pops stack into the instruction pointer (EIP or IP). Control transfers to the target address. Syntax: RET RET n Optional operand n causes n bytes to be added to the stack pointer after EIP (or IP) is assigned a value.
462
PROTO Directive Creates a procedure prototype Syntax:
label PROTO paramList Every procedure called by the INVOKE directive must have a prototype A complete procedure definition can also serve as its own prototype
463
PROTO Directive Standard configuration: PROTO appears at top of the program listing, INVOKE appears in the code segment, and the procedure implementation occurs later in the program: MySub PROTO ; procedure prototype .code INVOKE MySub ; procedure call MySub PROC ; procedure implementation . MySub ENDP
464
PROTO Example Prototype for the ArraySum procedure, showing its parameter list: ArraySum PROTO, ptrArray:PTR DWORD, ; points to the array szArray:DWORD ; array size
465
Passing by Value When a procedure argument is passed by value, a copy of a 16-bit or 32-bit integer is pushed on the stack. Example: .data myData WORD 1000h .code main PROC INVOKE Sub1, myData push myData call Sub1 MASM generates the following code:
466
Passing by Reference When an argument is passed by reference, its address is pushed on the stack. Example: .data myData WORD 1000h .code main PROC INVOKE Sub1, ADDR myData push OFFSET myData call Sub1 MASM generates the following code:
467
Parameter Classifications
An input parameter is data passed by a calling program to a procedure. The called procedure is not expected to modify the corresponding parameter variable, and even if it does, the modification is confined to the procedure itself. An output parameter is created by passing a pointer to a variable when a procedure is called. The procedure does not use any existing data from the variable, but it fills in a new value before it returns. An input-output parameter represents a value passed as input to a procedure, which the procedure may modify. The same parameter is then able to return the changed data to the calling program.
468
Example: Exchanging Two Integers
The Swap procedure exchanges the values of two 32-bit integers. pValX and pValY do not change values, but the integers they point to are modified. Swap PROC USES eax esi edi, pValX:PTR DWORD, ; pointer to first integer pValY:PTR DWORD ; pointer to second integer mov esi,pValX ; get pointers mov edi,pValY mov eax,[esi] ; get first integer xchg eax,[edi] ; exchange with second mov [esi],eax ; replace first integer ret Swap ENDP
469
Trouble-Shooting Tips
Save and restore registers when they are modified by a procedure. Except a register that returns a function result When using INVOKE, be careful to pass a pointer to the correct data type. For example, MASM cannot distinguish between a DWORD argument and a PTR BYTE argument. Do not pass an immediate value to a procedure that expects a reference parameter. Dereferencing its address will likely cause a general-protection fault.
470
Stack Frames Memory Models Language Specifiers
Explicit Access to Stack Parameters Passing Arguments by Reference Creating Local Variables
471
Stack Frame Also known as an activation record
Area of the stack set aside for a procedure's return address, passed parameters, saved registers, and local variables Created by the following steps: Calling program pushes arguments on the stack and calls the procedure. The called procedure pushes EBP on the stack, and sets EBP to ESP. If local variables are needed, a constant is subtracted from ESP to make room on the stack.
472
Memory Models A program's memory model determines the number and sizes of code and data segments. Real-address mode supports tiny, small, medium, compact, large, and huge models. Protected mode supports only the flat model. Small model: code < 64 KB, data (including stack) < 64 KB. All offsets are 16 bits. Flat model: single segment for code and data, up to 4 GB. All offsets are 32 bits.
473
.MODEL Directive .MODEL directive specifies a program's memory model and model options (language-specifier). Syntax: .MODEL memorymodel [,modeloptions] memorymodel can be one of the following: tiny, small, medium, compact, large, huge, or flat modeloptions includes the language specifier: procedure naming scheme parameter passing conventions
474
Language Specifiers C:
procedure arguments pushed on stack in reverse order (right to left) calling program cleans up the stack pascal procedure arguments pushed in forward order (left to right) called procedure cleans up the stack stdcall
475
Explicit Access to Stack Parameters
A procedure can explicitly access stack parameters using constant offsets from EBP1. Example: [ebp + 8] EBP is often called the base pointer or frame pointer because it holds the base address of the stack frame. EBP does not change value during the procedure. EBP must be restored to its original value when a procedure returns. 1 BP in Real-address mode
476
Stack Frame Example (1 of 2)
.data sum DWORD ? .code push 6 ; second argument push 5 ; first argument call AddTwo ; EAX = sum mov sum,eax ; save the sum AddTwo PROC push ebp mov ebp,esp .
477
AddTwo Procedure (1 of 3) Recall the AddTwo Procedure AddTwo PROC,
val1:DWORD, val2:DWORD mov eax,val1 add eax,val2 ret AddTwo ENDP
478
AddTwo Procedure (2 of 3) MASM generates the following code when we assemble AddTwo (from the previous panel): AddTwo PROC, val1:DWORD, val2:DWORD push ebp mov ebp, esp mov eax,val1 add eax,val2 leave ret 8 AddTwo ENDP The LEAVE instruction is shorthand for: mov esp,ebp pop ebp
479
AddSub Procedure (3 of 3) AddTwo PROC push ebp
mov ebp,esp ; base of stack frame mov eax,[ebp + 12] ; second argument (6) add eax,[ebp + 8] ; first argument (5) leave ret 8 AddTwo ENDP ; EAX contains the sum
480
Your turn . . . Create a procedure named Difference that subtracts the first argument from the second one. Following is a sample call: push 14 ; first argument push 30 ; second argument call Difference ; EAX = 16 Difference PROC push ebp mov ebp,esp mov eax,[ebp + 8] ; second argument sub eax,[ebp + 12] ; first argument pop ebp ret 8 Difference ENDP
481
Passing Arguments by Reference (1 of 2)
The ArrayFill procedure fills an array with 16-bit random integers The calling program passes the address of the array, along with a count of the number of array elements: .data count = 100 array WORD count DUP(?) .code push OFFSET array push COUNT call ArrayFill
482
Passing Arguments by Reference (2 of 2)
ArrayFill can reference an array without knowing the array's name: ArrayFill PROC push ebp mov ebp,esp pushad mov esi,[ebp+12] mov ecx,[ebp+8] . ESI points to the beginning of the array, so it's easy to use a loop to access each array element. View the complete program.
483
LEA Instruction The LEA instruction returns offsets of both direct and indirect operands. OFFSET operator can only return constant offsets. LEA is required when obtaining the offset of a stack parameter or local variable. For example: CopyString PROC, count:DWORD LOCAL temp[20]:BYTE mov edi,OFFSET count ; invalid operand mov esi,OFFSET temp ; invalid operand lea edi,count ; ok lea esi,temp ; ok
484
Creating Local Variables
To explicitly create local variables, subtract their total size from ESP. The following example creates and initializes two 32-bit local variables (we'll call them locA and locB): MySub PROC push ebp mov ebp,esp sub esp,8 mov [ebp-4],123456h ; locA mov [ebp-8],0 ; locB .
485
Recursion What is recursion? Recursively Calculating a Sum
Calculating a Factorial
486
What is Recursion? The process created when . . .
A procedure calls itself Procedure A calls procedure B, which in turn calls procedure A Using a graph in which each node is a procedure and each edge is a procedure call, recursion forms a cycle:
487
Recursively Calculating a Sum
The CalcSum procedure recursively calculates the sum of an array of integers. Receives: ECX = count. Returns: EAX = sum CalcSum PROC cmp ecx,0 ; check counter value jz L2 ; quit if zero add eax,ecx ; otherwise, add to sum dec ecx ; decrement counter call CalcSum ; recursive call L2: ret CalcSum ENDP Stack frame: View the complete program
488
Calculating a Factorial (1 of 3)
This function calculates the factorial of integer n. A new value of n is saved in each stack frame: int function factorial(int n) { if(n == 0) return 1; else return n * factorial(n-1); } As each call instance returns, the product it returns is multiplied by the previous value of n.
489
Calculating a Factorial (2 of 3)
Factorial PROC push ebp mov ebp,esp mov eax,[ebp+8] ; get n cmp eax,0 ; n < 0? ja L1 ; yes: continue mov eax,1 ; no: return 1 jmp L2 L1: dec eax push eax ; Factorial(n-1) call Factorial ; Instructions from this point on execute when each ; recursive call returns. ReturnFact: mov ebx,[ebp+8] ; get n mul ebx ; ax = ax * bx L2: pop ebp ; return EAX ret 4 ; clean up stack Factorial ENDP See the program listing
490
Calculating a Factorial (3 of 3)
Suppose we want to calculate 12! This diagram shows the first few stack frames created by recursive calls to Factorial Each recursive call uses 12 bytes of stack space.
491
Multimodule Programs A multimodule program is a program whose source code has been divided up into separate ASM files. Each ASM file (module) is assembled into a separate OBJ file. All OBJ files belonging to the same program are linked using the link utility into a single EXE file. This process is called static linking
492
Advantages Large programs are easier to write, maintain, and debug when divided into separate source code modules. When changing a line of code, only its enclosing module needs to be assembled again. Linking assembled modules requires little time. A module can be a container for logically related code and data (think object-oriented here...) encapsulation: procedures and variables are automatically hidden in a module unless you declare them public
493
Creating a Multimodule Program
Here are some basic steps to follow when creating a multimodule program: Create the main module Create a separate source code module for each procedure or set of related procedures Create an include file that contains procedure prototypes for external procedures (ones that are called between modules) Use the INCLUDE directive to make your procedure prototypes available to each module
494
Example: ArraySum Program
Let's review the ArraySum program from Chapter 5. Each of the four white rectangles will become a module.
495
Sample Program output Enter a signed integer: -25
The sum of the integers is: +53
496
INCLUDE File The sum.inc file contains prototypes for external functions that are not in the Irvine32 library: INCLUDE Irvine32.inc PromptForIntegers PROTO, ptrPrompt:PTR BYTE, ; prompt string ptrArray:PTR DWORD, ; points to the array arraySize:DWORD ; size of the array ArraySum PROTO, count:DWORD ; size of the array DisplaySum PROTO, theSum:DWORD ; sum of the array
497
Inspect Individual Modules
Main PromptForIntegers ArraySum DisplaySum Custom batch file for assembling and linking.
498
String Primitive Instructions
MOVSB, MOVSW, and MOVSD CMPSB, CMPSW, and CMPSD SCASB, SCASW, and SCASD STOSB, STOSW, and STOSD LODSB, LODSW, and LODSD
499
MOVSB, MOVSW, and MOVSD (1 of 2)
The MOVSB, MOVSW, and MOVSD instructions copy data from the memory location pointed to by ESI to the memory location pointed to by EDI. .data source DWORD 0FFFFFFFFh target DWORD ? .code mov esi,OFFSET source mov edi,OFFSET target movsd
500
MOVSB, MOVSW, and MOVSD (2 of 2)
ESI and EDI are automatically incremented or decremented: MOVSB increments/decrements by 1 MOVSW increments/decrements by 2 MOVSD increments/decrements by 4
501
Direction Flag The Direction flag controls the incrementing or decrementing of ESI and EDI. DF = clear (0): increment ESI and EDI DF = set (1): decrement ESI and EDI The Direction flag can be explicitly changed using the CLD and STD instructions: CLD ; clear Direction flag STD ; set Direction flag
502
Using a Repeat Prefix REP (a repeat prefix) can be inserted just before MOVSB, MOVSW, or MOVSD. ECX controls the number of repetitions Example: Copy 20 doublewords from source to target .data source DWORD 20 DUP(?) target DWORD 20 DUP(?) .code cld ; direction = forward mov ecx,LENGTHOF source ; set REP counter mov esi,OFFSET source mov edi,OFFSET target rep movsd
503
Your turn . . . Use MOVSD to delete the first element of the following doubleword array. All subsequent array values must be moved one position forward toward the beginning of the array: array DWORD 1,1,2,3,4,5,6,7,8,9,10 .data array DWORD 1,1,2,3,4,5,6,7,8,9,10 .code cld mov ecx,(LENGTHOF array) - 1 mov esi,OFFSET array+4 mov edi,OFFSET array rep movsd
504
CMPSB, CMPSW, and CMPSD The CMPSB, CMPSW, and CMPSD instructions each compare a memory operand pointed to by ESI to a memory operand pointed to by EDI. CMPSB compares bytes CMPSW compares words CMPSD compares doublewords Repeat prefix often used REPE (REPZ) REPNE (REPNZ)
505
Comparing a Pair of Doublewords
If source > target, the code jumps to label L1; otherwise, it jumps to label L2 .data source DWORD 1234h target DWORD 5678h .code mov esi,OFFSET source mov edi,OFFSET target cmpsd ; compare doublewords ja L1 ; jump if source > target jmp L2 ; jump if source <= target
506
Your turn . . . Modify the program in the previous slide by declaring both source and target as WORD variables. Make any other necessary changes.
507
Comparing Arrays Use a REPE (repeat while equal) prefix to compare corresponding elements of two arrays. .data source DWORD COUNT DUP(?) target DWORD COUNT DUP(?) .code mov ecx,COUNT ; repetition count mov esi,OFFSET source mov edi,OFFSET target cld ; direction = forward repe cmpsd ; repeat while equal
508
Example: Comparing Two Strings (1 of 3)
This program compares two strings (source and destination). It displays a message indicating whether the lexical value of the source string is less than the destination string. .data source BYTE "MARTIN " dest BYTE "MARTINEZ" str1 BYTE "Source is smaller",0dh,0ah,0 str2 BYTE "Source is not smaller",0dh,0ah,0 Source is smaller Screen output:
509
Example: Comparing Two Strings (2 of 3)
.code main PROC cld ; direction = forward mov esi,OFFSET source mov edi,OFFSET dest mov ecx,LENGTHOF source repe cmpsb jb source_smaller mov edx,OFFSET str2 ; "source is not smaller" jmp done source_smaller: mov edx,OFFSET str1 ; "source is smaller" done: call WriteString exit main ENDP END main
510
Example: Comparing Two Strings (3 of 3)
The following diagram shows the final values of ESI and EDI after comparing the strings:
511
Your turn . . . Modify the String Comparison program from the previous two slides. Prompt the user for both the source and destination strings. Sample output: Input first string: ABCDEFG Input second string: ABCDDG The first string is not smaller.
512
SCASB, SCASW, and SCASD The SCASB, SCASW, and SCASD instructions compare a value in AL/AX/EAX to a byte, word, or doubleword, respectively, addressed by EDI. Useful types of searches: Search for a specific element in a long string or array. Search for the first element that does not match a given value.
513
SCASB Example Search for the letter 'F' in a string named alpha:
.data alpha BYTE "ABCDEFGH",0 .code mov edi,OFFSET alpha mov al,'F' ; search for 'F' mov ecx,LENGTHOF alpha cld repne scasb ; repeat while not equal jnz quit dec edi ; EDI points to 'F' What is the purpose of the JNZ instruction?
514
STOSB, STOSW, and STOSD The STOSB, STOSW, and STOSD instructions store the contents of AL/AX/EAX, respectively, in memory at the offset pointed to by EDI. Example: fill an array with 0FFh .data Count = 100 string1 BYTE Count DUP(?) .code mov al,0FFh ; value to be stored mov edi,OFFSET string1 ; ES:DI points to target mov ecx,Count ; character count cld ; direction = forward rep stosb ; fill with contents of AL
515
LODSB, LODSW, and LODSD LODSB, LODSW, and LODSD load a byte or word from memory at ESI into AL/AX/EAX, respectively. Example: .data array BYTE 1,2,3,4,5,6,7,8,9 .code mov esi,OFFSET array mov ecx,LENGTHOF array cld L1: lodsb ; load byte into AL or al,30h ; convert to ASCII call WriteChar ; display it loop L1
516
Array Multiplication Example
Multiply each element of a doubleword array by a constant value. .data array DWORD 1,2,3,4,5,6,7,8,9,10 multiplier DWORD 10 .code cld ; direction = up mov esi,OFFSET array ; source index mov edi,esi ; destination index mov ecx,LENGTHOF array ; loop counter L1: lodsd ; copy [ESI] into EAX mul multiplier ; multiply by a value stosd ; store EAX at [EDI] loop L1
517
Your turn . . . Write a program that converts each unpacked binary-coded decimal byte belonging to an array into an ASCII decimal byte and copies it to a new array. .data array BYTE 1,2,3,4,5,6,7,8,9 dest BYTE (LENGTHOF array) DUP(?) mov esi,OFFSET array mov edi,OFFSET dest mov ecx,LENGTHOF array cld L1: lodsb ; load into AL or al,30h ; convert to ASCII stosb ; store into memory loop L1
518
Selected String Procedures
The following string procedures may be found in the Irvine32 and Irvine16 libraries: Str_compare Procedure Str_length Procedure Str_copy Procedure Str_trim Procedure Str_ucase Procedure
519
Str_compare Procedure
Compares string1 to string2, setting the Carry and Zero flags accordingly Prototype: Str_compare PROTO, string1:PTR BYTE, ; pointer to string string2:PTR BYTE ; pointer to string For example, if string1 > string2, CF=0, ZF=0 Or, if string1 < string2, CF=1, ZF=0
520
Str_compare Source Code
Str_compare PROC USES eax edx esi edi, string1:PTR BYTE, string2:PTR BYTE mov esi,string1 mov edi,string2 L1: mov al,[esi] mov dl,[edi] cmp al, ; end of string1? jne L ; no cmp dl, ; yes: end of string2? jmp L ; yes, exit with ZF = 1 L2: inc esi ; point to next inc edi cmp al,dl ; chars equal? je L ; yes: continue loop L3: ret Str_compare ENDP
521
Str_length Procedure Calculates the length of a null-terminated string and returns the length in the EAX register. Prototype: Str_length PROTO, pString:PTR BYTE ; pointer to string .data myString BYTE "abcdefg",0 .code INVOKE Str_length, ADDR myString ; EAX = 7 Example:
522
Str_length Source Code
Str_length PROC USES edi, pString:PTR BYTE ; pointer to string mov edi,pString mov eax, ; character count L1: cmp byte ptr [edi],0 ; end of string? je L2 ; yes: quit inc edi ; no: point to next inc eax ; add 1 to count jmp L1 L2: ret Str_length ENDP
523
Str_copy Procedure Copies a null-terminated string from a source location to a target location. Prototype: Str_copy PROTO, source:PTR BYTE, ; pointer to string target:PTR BYTE ; pointer to string See the CopyStr.asm program for a working example.
524
Str_copy Source Code Str_copy PROC USES eax ecx esi edi,
source:PTR BYTE, ; source string target:PTR BYTE ; target string INVOKE Str_length,source ; EAX = length source mov ecx,eax ; REP count inc ecx ; add 1 for null byte mov esi,source mov edi,target cld ; direction = up rep movsb ; copy the string ret Str_copy ENDP
525
Str_trim Procedure The Str_trim procedure removes all occurrences of a selected trailing character from a null-terminated string. Prototype: Str_trim PROTO, pString:PTR BYTE, ; points to string char:BYTE ; char to remove .data myString BYTE "Hello###",0 .code INVOKE Str_trim, ADDR myString, '#' myString = "Hello" Example:
526
Str_trim Procedure Str_trim checks a number of possible cases (shown here with # as the trailing character): The string is empty. The string contains other characters followed by one or more trailing characters, as in "Hello##". The string contains only one character, the trailing character, as in "#" The string contains no trailing character, as in "Hello" or "H". The string contains one or more trailing characters followed by one or more nontrailing characters, as in "#H" or "###Hello".
527
Str_trim Source Code Str_trim PROC USES eax ecx edi,
pString:PTR BYTE, ; points to string char:BYTE ; char to remove mov edi,pString INVOKE Str_length,edi ; returns length in EAX cmp eax,0 ; zero-length string? je L2 ; yes: exit mov ecx,eax ; no: counter = string length dec eax add edi,eax ; EDI points to last char mov al,char ; char to trim std ; direction = reverse repe scasb ; skip past trim character jne L1 ; removed first character? dec edi ; adjust EDI: ZF=1 && ECX=0 L1: mov BYTE PTR [edi+2],0 ; insert null byte L2: ret Str_trim ENDP
528
Str_ucase Procedure The Str_ucase procedure converts a string to all uppercase characters. It returns no value. Prototype: Str_ucase PROTO, pString:PTR BYTE ; pointer to string .data myString BYTE "Hello",0 .code INVOKE Str_ucase, ADDR myString Example:
529
Str_ucase Source Code Str_ucase PROC USES eax esi, pString:PTR BYTE
mov esi,pString L1: mov al,[esi] ; get char cmp al,0 ; end of string? je L3 ; yes: quit cmp al,'a' ; below "a"? jb L2 cmp al,'z' ; above "z"? ja L2 and BYTE PTR [esi], b ; convert the char L2: inc esi ; next char jmp L1 L3: ret Str_ucase ENDP
530
Two-Dimensional Arrays
Base-Index Operands Base-Index Displacement
531
Base-Index Operand A base-index operand adds the values of two registers (called base and index), producing an effective address. Any two 32-bit general-purpose registers may be used. Base-index operands are great for accessing arrays of structures. (A structure groups together data under a single name. )
532
Structure Application
A common application of base-index addressing has to do with addressing arrays of structures (Chapter 10). The following definds a structure named COORD containing X and Y screen coordinates: COORD STRUCT X WORD ? ; offset 00 Y WORD ? ; offset 02 COORD ENDS Then we can define an array of COORD objects: .data setOfCoordinates COORD 10 DUP(<>)
533
Structure Application
The following code loops through the array and displays each Y-coordinate: mov ebx,OFFSET setOfCoordinates mov esi,2 ; offset of Y value mov eax,0 L1: mov ax,[ebx+esi] call WriteDec add ebx,SIZEOF COORD loop L1
534
Base-Index-Displacement Operand
A base-index-displacement operand adds base and index registers to a constant, producing an effective address. Any two 32-bit general-purpose registers may be used. Common formats: [ base + index + displacement ] displacement [ base + index ]
535
Two-Dimensional Table Example
Imagine a table with three rows and five columns. The data can be arranged in any format on the page: table BYTE 10h, 20h, 30h, 40h, 50h BYTE 60h, 70h, 80h, 90h, 0A0h BYTE 0B0h, 0C0h, 0D0h, 0E0h, 0F0h NumCols = 5 table BYTE 10h,20h,30h,40h,50h,60h,70h, 80h,90h,0A0h, 0B0h,0C0h,0D0h, 0E0h,0F0h NumCols = 5 Alternative format:
536
Two-Dimensional Table Example
The following code loads the table element stored in row 1, column 2: RowNumber = 1 ColumnNumber = 2 mov ebx,NumCols * RowNumber mov esi,ColumnNumber mov al,table[ebx + esi]
537
Searching and Sorting Integer Arrays
Bubble Sort A simple sorting algorithm that works well for small arrays Binary Search A simple searching algorithm that works well for large arrays of values that have been placed in either ascending or descending order
538
Bubble Sort Each pair of adjacent values is compared, and exchanged if the values are not ordered correctly:
539
Bubble Sort Pseudocode
N = array size, cx1 = outer loop counter, cx2 = inner loop counter: cx1 = N - 1 while( cx1 > 0 ) { esi = addr(array) cx2 = cx1 while( cx2 > 0 ) if( array[esi] < array[esi+4] ) exchange( array[esi], array[esi+4] ) add esi,4 dec cx2 } dec cx1
540
Bubble Sort Implementation
BubbleSort PROC USES eax ecx esi, pArray:PTR DWORD,Count:DWORD mov ecx,Count dec ecx ; decrement count by 1 L1: push ecx ; save outer loop count mov esi,pArray ; point to first value L2: mov eax,[esi] ; get array value cmp [esi+4],eax ; compare a pair of values jge L3 ; if [esi] <= [edi], skip xchg eax,[esi+4] ; else exchange the pair mov [esi],eax L3: add esi,4 ; move both pointers forward loop L2 ; inner loop pop ecx ; retrieve outer loop count loop L1 ; else repeat outer loop L4: ret BubbleSort ENDP
541
Binary Search Searching algorithm, well-suited to large ordered data sets Divide and conquer strategy Each "guess" divides the list in half Classified as an O(log n) algorithm: As the number of array elements increases by a factor of n, the average search time increases by a factor of log n.
542
Binary Search Estimates
543
Binary Search Pseudocode
int BinSearch( int values[], const int searchVal, int count ) { int first = 0; int last = count - 1; while( first <= last ) int mid = (last + first) / 2; if( values[mid] < searchVal ) first = mid + 1; else if( values[mid] > searchVal ) last = mid - 1; else return mid; // success } return -1; // not found
544
Binary Search Implementation (1 of 3)
BinarySearch PROC uses ebx edx esi edi, pArray:PTR DWORD, ; pointer to array Count:DWORD, ; array size searchVal:DWORD ; search value LOCAL first:DWORD, ; first position last:DWORD, ; last position mid:DWORD ; midpoint mov first,0 ; first = 0 mov eax,Count ; last = (count - 1) dec eax mov last,eax mov edi,searchVal ; EDI = searchVal mov ebx,pArray ; EBX points to the array L1: ; while first <= last mov eax,first cmp eax,last jg L5 ; exit search
545
Binary Search Implementation (2 of 3)
; mid = (last + first) / 2 mov eax,last add eax,first shr eax,1 mov mid,eax ; EDX = values[mid] mov esi,mid shl esi,2 ; scale mid value by 4 mov edx,[ebx+esi] ; EDX = values[mid] ; if ( EDX < searchval(EDI) ) ; first = mid + 1; cmp edx,edi jge L2 mov eax,mid ; first = mid + 1 inc eax mov first,eax jmp L4 ; continue the loop base-index addressing
546
Binary Search Implementation (3 of 3)
; else if( EDX > searchVal(EDI) ) ; last = mid - 1; L2: cmp edx,edi ; (could be removed) jle L3 mov eax,mid ; last = mid - 1 dec eax mov last,eax jmp L4 ; continue the loop ; else return mid L3: mov eax,mid ; value found jmp L9 ; return (mid) L4: jmp L1 ; continue the loop L5: mov eax,-1 ; search failed L9: ret BinarySearch ENDP
547
Structures - Overview Defining Structures
Declaring Structure Variables Referencing Structure Variables Example: Displaying the System Time Nested Structures Example: Drunkard's Walk Declaring and Using Unions
548
Structure A template or pattern given to a logically related group of variables. field - structure member containing data Program access to a structure: entire structure as a complete unit individual fields Useful way to pass multiple related arguments to a procedure example: file directory information
549
Using a Structure Using a structure involves three sequential steps:
1. Define the structure. 2. Declare one or more variables of the structure type, called structure variables. 3. Write runtime instructions that access the structure.
550
Structure Definition Syntax
name STRUCT field-declarations name ENDS Field-declarations are identical to variable declarations
551
COORD Structure The COORD structure used by the MS-Windows programming library identifies X and Y screen coordinates COORD STRUCT X WORD ? ; offset 00 Y WORD ? ; offset 02 COORD ENDS
552
Employee Structure A structure is ideal for combining fields of different types: Employee STRUCT IdNum BYTE " " LastName BYTE 30 DUP(0) Years WORD 0 SalaryHistory DWORD 0,0,0,0 Employee ENDS
553
Declaring Structure Variables
Structure name is a user-defined type Insert replacement initializers between brackets: < > Empty brackets <> retain the structure's default field initializers Examples: .data point1 COORD <5,10> point2 COORD <> worker Employee <>
554
Initializing Array Fields
Use the DUP operator to initialize one or more elements of an array field: .data emp Employee <,,,2 DUP(20000)>
555
Array of Structures An array of structure objects can be defined using the DUP operator. Initializers can be used NumPoints = 3 AllPoints COORD NumPoints DUP(<0,0>) RD_Dept Employee 20 DUP(<>) accounting Employee 10 DUP(<,,,4 DUP(20000) >)
556
Referencing Structure Variables
Employee STRUCT ; bytes IdNum BYTE " " ; 9 LastName BYTE 30 DUP(0) ; 30 Years WORD 0 ; 2 SalaryHistory DWORD 0,0,0,0 ; 16 Employee ENDS ; 57 .data worker Employee <> mov eax,TYPE Employee ; 57 mov eax,SIZEOF Employee ; 57 mov eax,SIZEOF worker ; 57 mov eax,TYPE Employee.SalaryHistory ; 4 mov eax,LENGTHOF Employee.SalaryHistory ; 4 mov eax,SIZEOF Employee.SalaryHistory ; 16
557
. . . continued mov dx,worker.Years
mov worker.SalaryHistory, ; first salary mov worker.SalaryHistory+4, ; second salary mov edx,OFFSET worker.LastName mov esi,OFFSET worker mov ax,(Employee PTR [esi]).Years mov ax,[esi].Years ; invalid operand (ambiguous)
558
Looping Through an Array of Points
Sets the X and Y coordinates of the AllPoints array to sequentially increasing values (1,1), (2,2), ... .data NumPoints = 3 AllPoints COORD NumPoints DUP(<0,0>) .code mov edi,0 ; array index mov ecx,NumPoints ; loop counter mov ax,1 ; starting X, Y values L1: mov (COORD PTR AllPoints[edi]).X,ax mov (COORD PTR AllPoints[edi]).Y,ax add edi,TYPE COORD inc ax Loop L1
559
Example: Displaying the System Time (1 of 3)
Retrieves and displays the system time at a selected screen location. Uses COORD and SYSTEMTIME structures: SYSTEMTIME STRUCT wYear WORD ? wMonth WORD ? wDayOfWeek WORD ? wDay WORD ? wHour WORD ? wMinute WORD ? wSecond WORD ? wMilliseconds WORD ? SYSTEMTIME ENDS
560
Example: Displaying the System Time (2 of 3)
GetStdHandle gets the standard console output handle. SetConsoleCursorPosition positions the cursor. GetLocalTime gets the current time of day. .data sysTime SYSTEMTIME <> XYPos COORD <10,5> consoleHandle DWORD ? .code INVOKE GetStdHandle, STD_OUTPUT_HANDLE mov consoleHandle,eax INVOKE SetConsoleCursorPosition, consoleHandle, XYPos INVOKE GetLocalTime, ADDR sysTime
561
Example: Displaying the System Time (3 of 3)
Display the time using library calls: mov edx,OFFSET TheTimeIs ; "The time is " call WriteString movzx eax,sysTime.wHour ; hours call WriteDec mov edx,offset colonStr ; ":" movzx eax,sysTime.wMinute ; minutes movzx eax,sysTime.wSecond ; seconds
562
Nested Structures (1 of 2)
Define a structure that contains other structures. Used nested braces (or brackets) to initialize each COORD structure. COORD STRUCT X WORD ? Y WORD ? COORD ENDS Rectangle STRUCT UpperLeft COORD <> LowerRight COORD <> Rectangle ENDS .code rect1 Rectangle { {10,10}, {50,20} } rect2 Rectangle < <10,10>, <50,20> >
563
Nested Structures (2 of 2)
Use the dot (.) qualifier to access nested fields. Use indirect addressing to access the overall structure or one of its fields mov rect1.UpperLeft.X, 10 mov esi,OFFSET rect1 mov (Rectangle PTR [esi]).UpperLeft.Y, 10 // use the OFFSET operator mov edi,OFFSET rect2.LowerRight mov (COORD PTR [edi]).X, 50 mov edi,OFFSET rect2.LowerRight.X mov WORD PTR [edi], 50
564
Example: Drunkard's Walk
Random-path simulation Uses a nested structure to accumulate path data as the simulation is running Uses a multiple branch structure to choose the direction WalkMax = 50 DrunkardWalk STRUCT path COORD WalkMax DUP(<0,0>) pathsUsed WORD 0 DrunkardWalk ENDS View the source code
565
Declaring and Using Unions
A union is similar to a structure in that it contains multiple fields All of the fields in a union begin at the same offset (differs from a structure) Provides alternate ways to access the same data Syntax: unionname UNION union-fields unionname ENDS
566
Integer Union Example The Integer union consumes 4 bytes (equal to the largest field) Integer UNION D DWORD 0 W WORD 0 B BYTE 0 Integer ENDS D, W, and B are often called variant fields. Integer can be used to define data: .data val1 Integer < h> val2 Integer <100h> val3 Integer <>
567
Integer Union Example The variant field name is required when accessing the union: mov val3.B, al mov ax,val3.W add val3.D, eax
568
Union Inside a Structure
An Integer union can be enclosed inside a FileInfo structure: Integer UNION D DWORD 0 W WORD 0 B BYTE 0 Integer ENDS FileInfo STRUCT FileID Integer <> FileName BYTE 64 DUP(?) FileInfo ENDS .data myFile FileInfo <> .code mov myFile.FileID.W, ax
569
Macros Introducing Macros Defining Macros Invoking Macros
Macro Examples Nested Macros Example Program: Wrappers
570
Introducing Macros A macro1 is a named block of assembly language statements. Once defined, it can be invoked (called) one or more times. During the assembler's preprocessing step, each macro call is expanded into a copy of the macro. The expanded code is passed to the assembly step, where it is checked for correctness. 1Also called a macro procedure.
571
Defining Macros A macro must be defined before it can be used.
Parameters are optional. Each parameter follows the rules for identifiers. It is a string that is assigned a value when the macro is invoked. Syntax: macroname MACRO [parameter-1, parameter-2,...] statement-list ENDM
572
mNewLine Macro Example
This is how you define and invoke a simple macro. mNewLine MACRO ; define the macro call Crlf ENDM .data .code mNewLine ; invoke the macro The assembler will substitute "call crlf" for "mNewLine".
573
mPutChar Macro Writes a single character to standard output.
mPutchar MACRO char push eax mov al,char call WriteChar pop eax ENDM Definition: .code mPutchar 'A' Invocation: 1 push eax 1 mov al,'A' 1 call WriteChar 1 pop eax viewed in the listing file Expansion:
574
Invoking Macros (1 of 2) When you invoke a macro, each argument you pass matches a declared parameter. Each parameter is replaced by its corresponding argument when the macro is expanded. When a macro expands, it generates assembly language source code. Arguments are treated as simple text by the preprocessor.
575
Invoking Macros (2 of 2) Relationships between macros, arguments, and parameters:
576
mWriteStr Macro (1 of 2) Provides a convenient way to display a string, by passing the string name as an argument. mWriteStr MACRO buffer push edx mov edx,OFFSET buffer call WriteString pop edx ENDM .data str1 BYTE "Welcome!",0 .code mWriteStr str1
577
mWriteStr Macro (2 of 2) The expanded code shows how the str1 argument replaced the parameter named buffer: mWriteStr MACRO buffer push edx mov edx,OFFSET buffer call WriteString pop edx ENDM 1 push edx 1 mov edx,OFFSET str1 1 call WriteString 1 pop edx
578
Invalid Argument If you pass an invalid argument, the error is caught when the expanded code is assembled. Example: .code mPutchar 1234h 1 push eax 1 mov al,1234h ; error! 1 call WriteChar 1 pop eax
579
Blank Argument If you pass a blank argument, the error is also caught when the expanded code is assembled. Example: .code mPutchar 1 push eax 1 mov al, 1 call WriteChar 1 pop eax
580
Macro Examples mReadStr - reads string from standard input
mGotoXY - locates the cursor on screen mDumpMem - dumps a range of memory
581
mReadStr The mReadStr macro provides a convenient wrapper around ReadString procedure calls. mReadStr MACRO varName push ecx push edx mov edx,OFFSET varName mov ecx,(SIZEOF varName) - 1 call ReadString pop edx pop ecx ENDM .data firstName BYTE 30 DUP(?) .code mReadStr firstName
582
mGotoXY The mGotoXY macro ets the console cursor position by calling the Gotoxy library procedure. mGotoxy MACRO X:REQ, Y:REQ push edx mov dh,Y mov dl,X call Gotoxy pop edx ENDM The REQ next to X and Y identifies them as required parameters.
583
mDumpMem The mDumpMem macro streamlines calls to the link library's DumpMem procedure. mDumpMem MACRO address, itemCount, componentSize push ebx push ecx push esi mov esi,address mov ecx,itemCount mov ebx,componentSize call DumpMem pop esi pop ecx pop ebx ENDM
584
mDump The mDump macro displays a variable, using its known attributes. If <useLabel> is nonblank, the name of the variable is displayed. mDump MACRO varName:REQ, useLabel IFB <varName> EXITM ENDIF call Crlf IFNB <useLabel> mWrite "Variable name: &varName" ELSE mWrite " " mDumpMem OFFSET varName, LENGTHOF varName, TYPE varName ENDM
585
mWrite The mWrite macro writes a string literal to standard output. It is a good example of a macro that contains both code and data. mWrite MACRO text LOCAL string .data ;; data segment string BYTE text,0 ;; define local string .code ;; code segment push edx mov edx,OFFSET string call Writestring pop edx ENDM The LOCAL directive prevents string from becoming a global label.
586
Nested Macros The mWriteLn macro contains a nested macro (a macro invoked by another macro). mWriteLn MACRO text mWrite text call Crlf ENDM mWriteLn "My Sample Macro Program" 2 .data 2 ??0002 BYTE "My Sample Macro Program",0 2 .code 2 push edx 2 mov edx,OFFSET ??0002 2 call Writestring 2 pop edx 1 call Crlf nesting level
587
Your turn . . . Write a nested macro named mAskForString that clears the screen, locates the cursor at a given row and column, prompts the user, and inputs a string. Use any macros shown so far. Use the following code and data to test your macro: .data acctNum BYTE 30 DUP(?) .code main proc mAskForString 5,10,"Input Account Number: ", \ acctNum Solution . . .
588
. . . Solution View the solution program
mAskForString MACRO row, col, prompt, inbuf call Clrscr mGotoXY col, row mWrite prompt mReadStr inbuf ENDM View the solution program
589
Example Program: Wrappers
The Wraps.asm program demonstrates various macros from this chapter. It shows how macros can simplify the passing of register arguments to library procedures. View the source code
590
Conditional-Assembly Directives
Checking for Missing Arguments Default Argument Initializers Boolean Expressions IF, ELSE, and ENDIF Directives The IFIDN and IFIDNI Directives Special Operators Macro Functions
591
Checking for Missing Arguments
The IFB directive returns true if its argument is blank. For example: IFB <row> ;; if row is blank, EXITM ;; exit the macro ENDIF
592
mWriteString Example Display a message during assembly if the string parameter is empty: mWriteStr MACRO string IFB <string> ECHO ECHO * Error: parameter missing in mWriteStr ECHO * (no code generated) EXITM ENDIF push edx mov edx,OFFSET string call WriteString pop edx ENDM
593
Default Argument Initializers
A default argument initializer automatically assigns a value to a parameter when a macro argument is left blank. For example, mWriteln can be invoked either with or without a string argument: mWriteLn MACRO text:=<" "> mWrite text call Crlf ENDM .code mWriteln "Line one" mWriteln mWriteln "Line three" Sample output: Line one Line three
594
Boolean Expressions A boolean expression can be formed using the following operators: LT - Less than GT - Greater than EQ - Equal to NE - Not equal to LE - Less than or equal to GE - Greater than or equal to Only assembly-time constants may be compared using these operators.
595
IF, ELSE, and ENDIF Directives
A block of statements is assembled if the boolean expression evaluates to true. An alternate block of statements can be assembled if the expression is false. IF boolean-expression statements [ELSE statements] ENDIF
596
Simple Example The following IF directive permits two MOV instructions to be assembled if a constant named RealMode is equal to 1: IF RealMode EQ 1 mov mov ds,ax ENDIF RealMode can be defined in the source code any of the following ways: RealMode = 1 RealMode EQU 1 RealMode TEXTEQU 1
597
The IFIDN and IFIDNI Directives
IFIDN compares two symbols and returns true if they are equal (case-sensitive) IFIDNI also compares two symbols, using a case-insensitive comparison Syntax: IFIDNI <symbol>, <symbol> statements ENDIF Can be used to prevent the caller of a macro from passing an argument that would conflict with register usage inside the macro.
598
IFIDNI Example Prevents the user from passing EDX as the second argument to the mReadBuf macro: mReadBuf MACRO bufferPtr, maxChars IFIDNI <maxChars>,<EDX> ECHO Warning: Second argument cannot be EDX ECHO ************************************** EXITM ENDIF . ENDM
599
Special Operators The substitution (&) operator resolves ambiguous references to parameter names within a macro. The expansion operator (%) expands text macros or converts constant expressions into their text representations. The literal-text operator (<>) groups one or more characters and symbols into a single text literal. It prevents the preprocessor from interpreting members of the list as separate arguments. The literal-character operator (!) forces the preprocessor to treat a predefined operator as an ordinary character.
600
Substitution (&) Text passed as regName is substituted into the literal string definition: ShowRegister MACRO regName .data tempStr BYTE " ®Name=",0 . .code ShowRegister EDX ; invoke the macro tempStr BYTE " EDX=",0 Macro expansion:
601
Expansion (%) Forces the evaluation of an integer expression. After the expression has been evaluated, its value is passed as a macro argument: mGotoXY %(5 * 10),%(3 + 4) The preprocessor generates the following code: 1 push edx 1 mov dl,50 1 mov dh,7 1 call Gotoxy 1 pop edx
602
Literal-Text (<>)
The first macro call passes three arguments. The second call passes a single argument: mWrite "Line three", 0dh, 0ah mWrite <"Line three", 0dh, 0ah>
603
Literal-Character (!) The following declaration prematurely ends the text definition when the first > character is reached. BadYValue TEXTEQU Warning: <Y-coordinate is > 24> The following declaration continues the text definition until the final > character is reached. BadYValue TEXTEQU <Warning: Y-coordinate is !> 24>
604
Notice how the assembler defines True and False.
Macro Functions (1 of 2) A macro function returns an integer or string constant The value is returned by the EXITM directive Example: The IsDefined macro acts as a wrapper for the IFDEF directive. IsDefined MACRO symbol IFDEF symbol EXITM <-1> ;; True ELSE EXITM <0> ;; False ENDIF ENDM Notice how the assembler defines True and False.
605
Macro Functions (2 of 2) When calling a macro function, the argument(s) must be enclosed in parentheses The following code permits the two MOV statements to be assembled only if the RealMode symbol has been defined: IF IsDefined( RealMode ) mov mov ds,ax ENDIF
606
Defining Repeat Blocks
WHILE Directive REPEAT Directive FOR Directive FORC Directive Example: Linked List
607
WHILE Directive The WHILE directive repeats a statement block as long as a particular constant expression is true. Syntax: WHILE constExpression statements ENDM
608
WHILE Example Generates Fibonacci integers between 1 and F h at assembly time: .data val1 = 1 val2 = 1 DWORD val1 ; first two values DWORD val2 val3 = val1 + val2 WHILE val3 LT 0F h DWORD val3 val1 = val2 val2 = val3 ENDM
609
REPEAT Directive The REPEAT directive repeats a statement block a fixed number of times. Syntax: REPEAT constExpression statements ENDM ConstExpression, an unsigned constant integer expression, determines the number of repetitions.
610
REPEAT Example The following code generates 100 integer data definitions in the sequence 10, 20, 30, . . . iVal = 10 REPEAT 100 DWORD iVal iVal = iVal + 10 ENDM How might we assign a data name to this list of integers?
611
Your turn . . . What will be the last integer to be generated by the following loop? 500 rows = 10 columns = 5 .data iVal = 10 REPEAT rows * columns DWORD iVal iVal = iVal + 10 ENDM
612
FOR Directive The FOR directive repeats a statement block by iterating over a comma-delimited list of symbols. Each symbol in the list causes one iteration of the loop. Syntax: FOR parameter,<arg1,arg2,arg3,...> statements ENDM
613
FOR Example The following Window structure contains frame, title bar, background, and foreground colors. The field definitions are created using a FOR directive: Window STRUCT FOR color,<frame,titlebar,background,foreground> color DWORD ? ENDM Window ENDS Generated code: Window STRUCT frame DWORD ? titlebar DWORD ? background DWORD ? foreground DWORD ? Window ENDS
614
FORC Directive The FORC directive repeats a statement block by iterating over a string of characters. Each character in the string causes one iteration of the loop. Syntax: FORC parameter, <string> statements ENDM
615
FORC Example Suppose we need to accumulate seven sets of integer data for an experiment. Their label names are to be Group_A, Group_B, Group_C, and so on. The FORC directive creates the variables: FORC code,<ABCDEFG> Group_&code WORD ? ENDM Generated code: Group_A WORD ? Group_B WORD ? Group_C WORD ? Group_D WORD ? Group_E WORD ? Group_F WORD ? Group_G WORD ?
616
Example: Linked List (1 of 5)
We can use the REPT directive to create a singly linked list at assembly time. Each node contains a pointer to the next node. A null pointer in the last node marks the end of the list
617
Linked List (2 of 5) Each node in the list is defined by a ListNode structure: ListNode STRUCT NodeData DWORD ? ; the node's data NextPtr DWORD ? ; pointer to next node ListNode ENDS TotalNodeCount = 15 NULL = 0 Counter = 0
618
Linked List (3 of 5) The REPEAT directive generates the nodes.
Each ListNode is initialized with a counter and an address that points 8 bytes beyond the current node's location: .data LinkedList LABEL PTR ListNode REPEAT TotalNodeCount Counter = Counter + 1 ListNode <Counter, ($ + Counter * SIZEOF ListNode)> ENDM The value of $ does not change—it remains fixed at the location of the LinkedList label.
619
Linked List (4 of 5) The following hexadecimal values in each node show how each NextPtr field contains the address of its following node. offset contents (etc.) NextPtr
620
Linked List (5 of 4) View the program's source code Sample output: 1 2
3 4 5 6 7 8 9 10 11 12 13 14 15 Sample output:
621
Program Statements Operation is a predefined or reserved word
name operation operand(s) comment Operation is a predefined or reserved word mnemonic - symbolic operation code directive - pseudo-operation code Space or tab separates initial fields Comments begin with semicolon Most assemblers are not case sensitive
622
Program Data and Storage
Pseudo-ops to define data or reserve storage DB - byte(s) DW - word(s) DD - doubleword(s) DQ - quadword(s) DT - tenbyte(s) These directives require one or more operands define memory contents specify amount of storage to reserve for run-time data
623
Defining Data Numeric data values
100 - decimal 100B - binary 100H - hexadecimal '100' - ASCII "100" - ASCII Use the appropriate DEFINE directive (byte, word, etc.) A list of values may be used - the following creates 4 consecutive words DW 40CH,10B,-13,0 A ? represents an uninitialized storage location DB 255,?,-128,'X'
624
Naming Storage Locations
Names can be associated with storage locations ANum DB -4 DW 17 ONE UNO DW 1 X DD ? These names are called variables ANum refers to a byte storage location, initialized to FCh The next word has no associated name ONE and UNO refer to the same word X is an unitialized doubleword
625
Arrays Any consecutive storage locations of the same size can be called an array X DW 40CH,10B,-13,0 Y DB 'This is an array' Z DD , FFFFFFFFH, -1, 100B Components of X are at X, X+2, X+4, X+8 Components of Y are at Y, Y+1, …, Y+15 Components of Z are at Z, Z+4, Z+8, Z+12
626
DUP Allows a sequence of storage locations to be defined or reserved
Only used as an operand of a define directive DB 40 DUP (?) DW 10h DUP (0) DB 3 dup ("ABC") db 4 dup(3 dup (0,1), 2 dup('$'))
627
Word Storage Word, doubleword, and quadword data are stored in reverse byte order (in memory) Directive Bytes in Storage DW DD H DQ A X DW 35DAh DA 35 Low byte of X is at X, high byte of X is at X+1
628
Named Constants Symbolic names associated with storage locations represent addresses Named constants are symbols created to represent specific values determined by an expression Named constants can be numeric or string Some named constants can be redefined No storage is allocated for these values
629
Equal Sign Directive name = expression expression must be numeric
these symbols may be redefined at any time maxint = 7FFFh count = 1 DW count count = count * 2
630
EQU Directive name EQU expression expression can be string or numeric
Use < and > to specify a string EQU these symbols cannot be redefined later in the program sample EQU 7Fh aString EQU <1.234> message EQU <This is a message>
631
Addresses with Displacements
b db 4Fh, 20h, 3Ch w dw 2048, -100, 0 mov bx, w+2 mov b+1, ah mov ah, b+5 mov dx, w-3 Type checking is still in effect The assembler computes an address based on the expression NOTE: These are address computations done at assembly time MOV ax, b-1 will not subtract 1 from the value stored at b
632
eXCHanGe XCHG target, source
reg, reg reg, mem mem, reg MOV and XCHG cannot perform memory to memory moves This provides an efficient means to swap the operands No temporary storage is needed Sorting often requires this type of operation This works only with the general registers
633
Arithmetic Instructions
ADD dest, source SUB dest, source INC dest DEC dest NEG dest Operands must be of the same size source can be a general register, memory location, or constant dest can be a register or memory location except operands cannot both be memory
634
Program Segment Structure
Data Segments Storage for variables Variable addresses are computed as offsets from start of this segment Code Segment contains executable instructions Stack Segment used to set aside storage for the stack Stack addresses are computed as offsets into this segment Segment directives .data .code .stack size
635
Memory Models .Model memory_model
tiny: code+data <= 64K (.com program) small: code<=64K, data<=64K, one of each medium: data<=64K, one data segment compact: code<=64K, one code segment large: multiple code and data segments huge: allows individual arrays to exceed 64K flat: no segments, 32-bit addresses, protected mode only (80386 and higher)
636
Program Skeleton .model small .stack 100H .data ;declarations .code
main proc ;code main endp ;other procs end main Select a memory model Define the stack size Declare variables Write code organize into procedures Mark the end of the source file optionally, define the entry point
637
Program stack Key characteristics
Stores temporary data during program execution One point of access – the top of the stack Last-in-first-out (LIFO) storage Data is retrieved in the reverse order from which it was stored Instructions that directly manipulate the stack PUSH – places data on top of stack POP – removes data from top of stack
638
Program stack PUSH – places data on top of stack
Example PUSH – places data on top of stack POP – removes data from top of stack
639
Temporary Register Storage
- Push and pop registers to preserve their value -Example: PUSH AX ; Place AX on the stack PUSH BX ; Place BX on the stack ... modify contents of Registers AX & BX ... POP BX ; Restore original ; value of BX POP AX ; Restore original ; value of AX The PUSH instruction does not change the contents of AX register
640
Procedures Stores Return Address of a procedure Example
PrintRec PROC NEAR ... Print value of a record ... Ret PrintRec ENDP Implicitly, The CALL statement stored the value of the Instruction Pointer (IP) on the stack. Therefore, the computer known how to return to exactly the next opcode in your program! main PROC FAR ... Calculate Scores ... CALL PrintRec Continue Execution HERE ... CALL DOSXIT main ENDP
641
Stack Implementation in Memory
SS : Stack Segment SP 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 can point to any element on the stack Recall that BP also uses SS
642
Implementation in memory
Program stack Implementation in memory Original SP In use Stack grows in direction of decreasing memory addresses In use Direction of increasing memory addresses In use In use In use In use SS:SP Free Free Free Free SS
643
Implementation in memory
Program stack Implementation in memory SS – Stack segment SP – Stack pointer always points to the top of the stack SP initially points to top of 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
644
Push example SS=0300 SP=0800 Therefore: SS:SP=03800 (Segment+Offset)
To address 12FFF Register array 03800 AX 6A 037FF PUSH BX BX 6AB3 B3 037FE CX DX SP before push SP after push SP 0800 SS 0300 03000 Stack segment
645
Pop example To address 0FFFF Register array 01008 AX 39 01007 POP BX
01006 CX DX SP after pop SP before pop SP 1006 SS 0000 00000 Stack segment
646
PUSH and POP PUSH and POP always store or retrieve words of data (never bytes) 80386 and above allow words or double words to be transferred to and from the stack Source of data for PUSH Any internal 16-bit register, immediate data, any segment register, or any two bytes of memory POP places data into Internal register, segment register (except CS), or a memory location
647
PUSH and POP -Example MOV AX,1 MOV BX,2 PUSH AX PUSH BX MOV AX,3
MOV AX,3 MOV BX,4 POP BX POP AX
648
More PUSH and POP instructions
The PUSHF pushes the Flags register on the stack. The POPF can be uses to restore the flags;s original state. 80286 and later include PUSHA and POPA to store and retrieve the contents internal register set (AX, BX, CX, DX, SP, BP, SI, DI)
649
Stack initialization example
Assume that the stack segment resides in memory locations 10000h – 1FFFFh The stack segment is loaded with 1000h The SP is loaded with 0000h This makes the stack 64KB First PUSH does 0000h – 0002h = FFFEh, storing data in 1FFFEh and 1FFFFh
650
Stack use To store To pass Registers
Return address information while procedures are executing Local variables that procedures may require Dynamically allocated memory To pass Parameters to procedures (function arguments)
651
Temporary register storage
PUSH and POP registers to preserve their values PUSH AX ; Place AX on the stack PUSH BX ; Place BX on the stack … < modify contents of AX and BX > POP BX ; Restore original value of BX POP AX ; Restore original value of AX
652
Temporary register storage
Why would you want to backup and restore registers? Because registers are themselves temporary storage for instruction operands or memory addresses You might need to do a task that modifies registers, but you might then need the original contents of those registers later Any data that is an end result more than likely should go into a memory location (a variable)
653
Procedures defined Procedures are chunks of code that usually perform specific frequently used tasks They can be repeatedly called from someplace else in your programs These are essentially the same thing as functions or subroutines in high-level languages Procedures may have inputs/outputs, both, either, neither Essentially just labeled blocks of assembly language instructions with a special return instruction at the end To call a subroutine implies that a return must take place. This not the same as a JUMP, which does not return.
654
PROC and ENDP Directives
The PROC and ENDP directives mark the beginning and ending of a procedure .CODE A10MAIN PROC FAR CALL B10 ;Call B10 ; ... MOV AX,4C00H ;End processing INT 21H A10MAIN ENDP ; B10 PROC NEAR CALL C10 ;Call C10 RET ;Return to B10 ENDP ; caller
655
Procedure example ;here’s my main program mov ax, 10h mov bx, 20h
mov cx, 30h mov dx, 40h call AddRegs ;this proc does AX + BX + CX + DX AX ;here’s the rest of my main program call DosExit ; AddRegs add ax, bx add ax, cx add ax, dx ret
656
Call Call does two things
It pushes the address of the instruction immediately following the call statement onto the stack It loads the instruction pointer with the value of the label marking the beginning of the procedure you’re calling (this is essentially an unconditional jump to the beginning of the procedure
657
Two kinds of calls Near calls Far calls
Allow jumps to procedures within the same code segment In this case, only the instruction pointer gets pushed onto the stack Far calls Allow jumps to anywhere in the memory space In this case, both the contents of the CS and IP registers get pushed onto the stack
658
Procedures Calling NEAR Subroutine - PUSH IP JUMP Offset My_Subroutine
Calling FAR My_Subroutine - PUSH CS - PUSH IP JUMP Segment My_subroutine : Offset My_Subroutine RET - POP IP (near routine) - POP IP - POP CS (far routine)
659
Passing parameters Using registers
Registers are the ultimate global variables Your proc can simply access information the calling program placed in specific registers Also a simple way for your proc to send data back to the caller The previous example used this method
660
Passing parameters Using global memory locations
Memory locations declared at the beginning of your program are global and can be accessed from any procedure Using a parameter block You may pass a pointer to an array or other type of memory block instead of an individual data value
661
Passing parameters Using the stack
Caller pushes all arguments expected by the proc onto the stack Proc can access these args directly from the stack by setting up the stack frame. push bp ; save value of bp mov bp, sp ; mark start of stack frame arg1 is at [ss:bp+4] assuming call arg1 is at [ss:bp+6] assuming call far
662
Example call proc to calculate area of right triangle.
;proc expects two word sized args to be on the stack push 3 push 4 call TriangleArea ;now we must remove the variables from the stack ;every push must be popped. add sp, 4 ; ax now contains 6
663
TriangleArea. push bp. mov bp, sp. y equ bp+4. ;[bp+4] = y. x equ bp+6
TriangleArea push bp mov bp, sp y equ bp+4 ;[bp+4] = y x equ bp+6 ;[bp+6] = x push dx mov ax, [y] ;same as mov ax, [bp+4] mul word [x] ;same as mul word, [bp+6] shr ax, 1 ;divide by two pop dx pop bp ret
664
What just happened… Push 3 Push 4 Call TriangleArea TriangleArea
push bp mov bp, sp push dx mov ax, [bp+4] mul word [bp+6] shr ax, 1 pop dx pop bp ret Add sp, 4 SP E Stack frame SP C 0003h SP A 0004h SP 8 Return IP SP 6 Saved BP BP SP 4 Saved DX 2 SS:0000
665
Local variable storage
You may allocate stack space for use as local variables within procedures Subtract from the stack pointer the number of bytes you need to allocate after setting up the stack frame At the end of your procedure, just add the same amount you subtracted to free the memory you allocated just before you pop bp In the procedure, use the stack frame to address local variable storage
666
Local variable storage
MyProc ;setup stack frame push bp mov bp, sp ;allocate space for two words sub sp, 4 ;access words at [bp-2] and [bp-4] … add sp, 4 ;destroy local variables pop bp ;restore original bp ret
667
Things to remember Always make sure that your stack is consistent (a proc doesn’t leave information on the stack that wasn’t there before the procedure ran) Always remember to save registers you modify that don’t contain return values
668
C style procedures Assembly procedures that can be called by C programs Must follow the same calling procedure that C compilers use when building C programs You can also call C functions from assembly programs using the same protocol
669
C style procedures Suppose a C program calls an assembly procedure as follows Proc1(a, b, c) Assume each argument is word-sized Further, assume the C compiler generates code to push a, b, and c onto the stack The assembly language procedure must be assembled with the correct ret (near or far) and stack handling of its procedures matching the corresponding values in the high-level module
670
C style procedures Assume C program always makes far call
So far return (retf) must end the C style procedure Return CS gets pushed onto the stack as well as return IP Makes a difference when accessing arguments using the stack frame C compilers push arguments in reverse order, from right to left. C is pushed first, then B, then A Lowest index from BP corresponds to first argument BP+10 c BP+8 b BP+6 a BP+4 Return CS BP+2 Return IP BP Saved BP Proc1(a, b, c)
671
C style procedures If the returned value needs four or fewer bytes, it is by default returned in registers one or two bytes - returned in AX three or four bytes - returned in AX (low word) and in DX (high byte or word), (in EAX in 32-bit mode) More than four bytes the called procedure stores data in some address and returns the offset and segment parts of that address in AX and DX, respectively
672
C style procedures Caller is responsible for clearing the arguments from the stack as soon as it regains control after the call this done by the compiler that generates the appropriate code a far procedure called from C should end with RETF instead of RET
673
Example Calling and ASM proc from a C program – the proc lets you display a string at a given row and column # include <stdio.h> extern void placeStr (char *, unsigned, unsigned); void main (void) { int n; for (n = 10; n < 20; ++n) placeStr (“This is the string”, n, 45); }
674
GLOBAL _placeStr SEGMENT code _placeStr set cursor position
; setup stack frame and save state PUSH BP MOV BP, SP PUSH AX PUSH BX PUSH DX ; get current page - returns in BH MOV AH, 0fh INT 10h ; read unsigned args 2 and 3 MOV DL, [BP+10] MOV DH, [BP+8] set cursor position MOV AH, 02h INT 10h ;point to string MOV BX, [BP+6] ;call outAsc to disp string call outAsc ;restore state POP DX POP BX POP AX POP BP RETF
675
Complete calling procedure
Program writes function parameters to stack (C is right-pusher) CALL saves program’s return address on the stack [PUSH CS (Far Proc); PUSH IP] Routine marks stack frame (PUSH BP; MOV BP, SP) Routine allocates stack memory for local variables (SUB SP, n) Routine saves registers it modifies (push SI, push BX, push CX) Subroutine Code Additional CALLs, PUSHs, POPs) Routine restores registers it modifies (pop CX, pop BX, pop SI) Routine deallocates stack memory for local variables (ADD SP, n) Routine restores original value of BP (POP BP) Subroutine Returns (RETF) Program clears parameters from stack (ADD SP,p)
676
INT Instruction F000:F065 STI CLD PUSH ES ….. IRST F066 2 F067 3 1 4
The INT instruction calls an operating system subroutine, identified by a number in the range 0-FFh. Before the INT is executed, AH usually contains a function number that identifies the desired subroutine ( AH , 09 request display ). The syntax is INT number . Figure illustrates the steps taken by the CPU when the INT is invoked by a program: The number following the INT tells the CPU which entry to locate in the interrupt vector table. The CPU jams to the address stored in the interrupt vector table ( F000:F065) The interrupt handler ( DOS subroutines ) at F000:F065 begins execution .(STI,CLD ,PUSH ES and performs the required operations) and finishes when the IRET instruction is reached. IRET ( interrupt return) causes the program to resume execution at the next instruction in the original calling program.POP the registers off the stack. The restored CS:IP causes a return to the instruction following INT. Calling program F000:F065 STI CLD PUSH ES ….. IRST MOV AH,10 INT 10h Add… F066 2 F067 3 1 4 3069 F000:F065 F000:AB62 Interrupt Vector Table
677
The stack and procedures
call proc_name Pushes the instruction pointer and sometimes the code segment register onto the stack Performs an unconditional jump to the label proc_name ret Pops saved IP and if necessary saved CS from the stack and back into the IP and CS registers This causes the instruction following the call statement to be executed next More on all of this procedure stuff tomorrow
678
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/macros
679
Program organization Good program organization helps with debugging
Programs do not work the first time Strategy to find problems Use TD and set breakpoints to check program progress Use comments to temporarily remove sections of code Use “print” statements to announce milestones in the progrm Test values and test cases Try forcing registers or variables to test output of a procedure Use “print” statements to display critical data Double-check your logic Try a different algorithm if all else fails
680
NASM directives Includes %include “drive:\path\filename” Definitions
DB/RESB define/reserve byte (8 bits) DW/RESW define/reserve word (16 bits) DD/RESD define/reserve doubleword (32 bits) EQU names a constant (has no effect on memory) Labels “.” prefixed “local” to previous non-dotted label “:” suffix not required and doesn’t change label Global.local can access dotted local labels anywhere by prepending previous non-dotted label
681
NASM directives Procedures
Labeled sections of code you can jump to and return from any point in your program Procedures begin with merely a non-dotted label Use dotted labels inside procedures to keep them local to the procedure Helps keep labels unique program-wide
682
NASM directives Macros
Procedures require some overhead in memory and execution time NASM replaces macro call with the macro code itself Advantages Faster (no call instruction) Readability – easier to understand program function Drawbacks Using the macro multiple times duplicates code Tricky to debug sometimes (especially when you have nested macros)
683
NASM directives References to procedures Segment definition
EXTERN name – gives you access to procedures and variables in other files (such as library files) GLOBAL name – makes your procedures and variables available to other files (as if you were creating a library) Segment definition SEGMENT name Examples: SEGMENT STACK SEGMENT CODE
684
Example program structure
; ECE291:MPXXX ; In this MP you will develop a program which take input ; from the keyboard ;====== Constants ================================================= ;ASCII values for common characters CR EQU 13 ; EQU’s have no effect on memory LF EQU 10 ; They are preprocessor directives only ESCKEY EQU 27 ; LF gets replace with 10 when assembled ;====== Externals ================================================= ; -- LIB291 Routines extern dspmsg, dspout, kbdin extern rsave, rrest, binasc
685
Example program structure
;==== LIBMPXXX Routines (Your code will replace calls to these ;functions) extern LibKbdHandler extern LibMouseHandler extern LibDisplayResult extern MPXXXXIT ;====== Stack ==================================================== stkseg segment STACK ; *** STACK SEGMENT *** resb 64*8 ; 64*8 = 512 Bytes of Stack stacktop: ;====== Begin Code/Data ========================================== codeseg segment CODE ; *** CODE SEGMENT ***
686
Example program structure
;====== Variables ============================================== inputValid db 0 ; 0: InputBuffer is not ready ; 1: InputBuffer is ready ;-1: Esc key pressed operandsStr db 'Operands: ','$' OutputBuffer 16 times db 0 ; Contains formatted output db ‘$’ ; (Should be terminated with '$') MAXBUFLENGTH EQU 24 InputBuffer MAXBUFLENGTH times db 0 ; Contains one line of user input db ‘$’ graphData %include “graphData.dat” ; data GLOBAL outputBuffer, inputValid, operandsStr GLOBAL graphData
687
Example program structure
;====== Procedures =========================================== KbdHandler <Your code here> MouseHandler DisplayResult ;====== Program Initialization =============================== ..start: mov ax, cs ; Use common code & data segment mov ds, ax mov sp, stacktop ; Initialize top of stack
688
Example program structure
;====== Main Procedure ======================================== MAIN: MOV AX, 0B800h ;Use extra segment to access video MOV ES, AX <here comes your main procedure> CALL MPXXXXIT ; Exit to DOS
689
Chapter 5 Software Interrupts
690
Lecture outline Interrupt vectors Software interrupts
Hardware interrupts 8259 Programmable Interrupt Controller INT 21h Instruction review
691
Interrupts Triggers that cause the CPU to perform various tasks on demand Three kinds: Software interrupts – initiated by the INT instruction Hardware interrupts – originate in peripheral hardware Exceptions – occur in response to error states in the processor Regardless of source, they are handled the same Each interrupt has a unique interrupt number from 0 to These are called interrupt vectors. For each interrupt vector, there is an entry in the interrupt vector table. The interrupt vector table is simply a jump table containing segment:offset addresses of procedures to handle each interrupt These procedures are called interrupt handlers or interrupt service routines (ISR’s)
692
Interrupt function pointer
Interrupt vectors The first 1024 bytes of memory (addresses – 003FF) always contain the interrupt vector table. Always. Never anything else. Each of the 256 vectors requires four bytes—two for segment, two for offset Memory address (hex) Interrupt function pointer 003FC 4 * x 00008 00004 00000 INT 255 INT x INT 2 INT 1 INT 0
693
Software interrupts Essentially just function calls using a different instruction to do the calling Software interrupts give you access to “built-in” code from BIOS, operating system, or peripheral devices Use the INT instruction to “call” these procedures
694
Common Software Interrupts
INT 10h Video Services - controls the cursor position, scrolls the screen, display video graphics INT 16h Keyboard Services - reads the keyboard & check status INT 17h Printer Services - initializes, prints, & checks status INT 1Ah Time of Day - gets clock-tick count INT 1Ch User Timer Interrupt - Does nothing 18.2 times per second INT 21h DOS Services - e.g., I/O, file handling, memory management
695
The INT and IRET instructions
Syntax: INT imm8 Imm8 is an interrupt vector from 0 to 255 INT does the following: Pushes flag register (pushf) Pushes return CS and IP Far jumps to [0000:(4*imm8)] Clears the interrupt flag disabling the interrupt system IRET is to INT what RET is to CALL Pops flag register Performs a far return
696
The INT and IRET instructions
The INT instruction calls an operating system subroutine, identified by a number in the range 0-FFh. Before the INT is executed, AH usually contains a function number that identifies the desired subroutine ( AH , 09 request display ). The syntax is INT number . Figure illustrates the steps taken by the CPU when the INT is invoked by a program: The number following the INT tells the CPU which entry to locate in the interrupt vector table. The CPU jams to the address stored in the interrupt vector table ( F000:F065) The interrupt handler ( DOS subroutines ) at F000:F065 begins execution .(STI,CLD ,PUSH ES and performs the required operations) and finishes when the IRET instruction is reached. IRET ( interrupt return) causes the program to resume execution at the next instruction in the original calling program.POP the registers off the stack. The restored CS:IP causes a return to the instruction following INT. Calling program F000:F065 STI CLD PUSH ES ….. IRET MOV AH,10 INT 10h Add… F066 2 F067 3 1 4 3069 F000:F065 F000:AB62 Interrupt Vector Table
697
Things to notice The interrupt vector table is just a big permanently located jump table The values of the jump table are pointers to code provided by bios, hardware, MS-DOS function call Interrupt service routines preserve the flags – the state of the computer should be completely unaltered by an ISR
698
MS-DOS Function Calls INT 21h, Subfunction: AH=3: (char in DL) AH=7: (result in AL) AH=3Dh: Open File AH=3Fh: Read File AH=3Eh: Close File AH=13h: Delete File (!) AH=2Ah: Get system date AH=2Ch: Get system time AH=2Ch: Read DOS Version AH=47h: Get Current Directory AH=48h: Allocate Memory block (specified in paragraphs==16 bytes) AH=49h: Free Memory block AH=4Bh: Load and execute program AH=4Ch: Terminate program (and free resources) With software interrupts, we can also define a sub-function by placing a value in a register. For example, to execute of the many DOS functions, you can specify a sub-function by loading a value into AH just before calling INT 21
699
INT 21h DOS provides INT 21h, which is called the DOS function dispatcher and supports functions such as: read from the keyboard, write to the screen, write to the printer, read and write to disk files, etc. INT 21h must be told which function is being requested this information is passed by placing the function number in the AH register depending on the function being used, other information may be needed
700
Output Functions - INT 21h, AH = 02h
DOS 1+ - WRITE CHARACTER TO STANDARD OUTPUT INPUT: AH = 02h DL = character to write OUTPUT Return: AL = last character output (despite the official docs which state nothing is returned)
701
Output Functions INT 21h, AH = 05h
Dos function 5 sends a single character to the printer. INPUT: AH=5, DL contains the character
702
Output Functions INT 21h, AH = 6
DOS 1+ - DIRECT CONSOLE OUTPUT INPUT: AH = 06h DL = character to output (except FFh) OUTPUT: Return: AL = character output (despite official docs which state nothing is returned) (at least DOS )
703
Displaying A Single Character Using INT 21h
Example: Suppose that the letter ‘A’ is to be printed to the screen at the current cursor position Can use function 02h or 06h INT 21h must also be told which letter to print the ASCII code must be placed into DL register MOV DL, ‘A’ MOV AH, 06h INT 21h
704
Output Functions -INT 21h, AH = 09h
DOS 1+ - WRITE STRING TO STANDARD OUTPUT INPUT : AH = 09h DX – contents the offset of the string Return: AL = 24h (the '$' terminating the string, despite official docs which state that nothing is returned)
705
Displaying A Character String Using INT 21h
DOS function 09h displays a character string that ends with ‘$’ MSG DB ‘This is a test line’,’$’ … MOV DX, MSG MOV AH, 09h INT 21h The string will be printed beginning at the current cursor position
706
Input Functions: 01h – Filtered input With Echo
06h – Direct Input Without Waiting 07h – Direct Input, No Ctrl-Break 08h – Direct input with Ctrl-Break 0Ah – Buffered Input 0Bh – Get Input Status OCh Clear Input Buffer, Invoke Input Function 3Fh – Read Form File Device
707
INT 21h, AH = 01h DOS 1+ - READ CHARACTER FROM STD INPUT, WITH ECHO
Return: AL = character read Notes: ^C/^Break are checked, and INT 23 executed if read. ^P toggles the DOS-internal echo-to-printer flag. ^Z is not interpreted, thus not causing an EOF if input is redirected. Character is echoed to standard output. Standard input is always the keyboard and standard output the screen under DOS 1.x, but they may be redirected under DOS 2+
708
Reading A Single Character Using INT 21h
DOS function 01h reads a single character typed from the keyboard and echoes that character to the screen MOV AH, 01h INT 21h The computer will wait until the user presses a key, then input character will be in AL
709
0Ah Buffered Input Function 0Ah reads a character string of up to 255 characters from standard input and stores it in a buffer. INPUT : AH = 0Ah DX – contains the offset of the record containing the keyboard parameters. . The format of this record is : n+1 offset 1 n m Number of characters allowed Number of characters actually input
710
3Fh – Read from File or Device
INPUT: ah = 3Fh bx=0 ; device =keyboard dx = offset cx = maximum number of characters to be typed OUTPUT ax = number of input characters See example : Chapter 13: Keybd.asm
711
Date/Time Functions Function 2Ah returns the current system date, placing the year number in CX, the month number in DH, the day number in DL and the day of the week in AL. The day number in AL, uses the value of 0 for Sundey , 1 for Monday …and so on. mov ah,2Ah Int 21h mov year,cx mov month,dh mov day,dl mov dayOfWeek, al See example : Chapter 13: DateTime.asm
712
BIOS – LEVEL Keyboard Input ( INT 16H)
A direct way to retrieve keyboard input is through the INT 16 h keyboard services. The function code is placed in AH before calling INT 16h The BIOS Data Area at location 40:1Eh contents the keyboard buffer. When you press a key , the keyboard’s processor automatically generates the key’s scan code and request BIOS INT 09h. INT 09h routine gets the scan code from the keyboard, converts it to an ASCII character, and delivers it to the keyboard buffer area. Subsequently , INT 16H reads the character from the buffer and delivers it to your program . Your program need never request INT 09h because the processor performs it automatically when you press a key.
713
How the Keyboard Works? Sc = scan code As = ASCII code Input port Sc
Sc , As INT 9h handler Typeahead buffer Sc , As As INT 21h handler INT 16h handler
714
INT 16h Function 03h : Set Typematic Repeat Rate
When you hold down a key for more than one-half second, the keyboard enters typematic mode and automatically repeats the character. To change the rate, you can use the function like this : mov ah,03h mov al,05h mov bh, repeat_delay mov bl, repat_rate The value for repeat- delay in BH are 0=1/4 sec.,1=1/2 sec.(default), 2=3/4 sec, and 3=1 sec. The values for repeat-rate in BL range from 0(fastest) through 31(slowest)
715
INT 16h Function 05h : Keyboard Write
This operation allows a user to insert characters in the keyboard buffer as if a user had pressed a key . Load the ASCII character into CH and its scan code into CL. If the buffer is full, the operation sets the Carry Flag and AL to 1. Example: mov ah,5 mov ch,1Eh mov cl,41h int 16h
716
INT 16h Function 10h : Read Keyboard Character
If a charter is entered, the operation delivers it to AL and its scan code to AH. If the pressed key is an extended function such as Home or F1, the character in AL: is 00h. Here are the three possibilities: Key Pressed AH AL Regular ASCII Character Scan code ASCII character Extended function key (F1) 00h Extended duplicate control key E0h
717
INT 16h Function 11h: Check Keyboard Buffer - Determine Whether Character is Present
If an entered character is present in the keyboard buffer, the operation clears the Zero Flag and delivers the character to AL and its scan code to AH; the entered character remains in the buffer. If no character is present, the operation sets the Zero Flag and does not wait. Note that the operation provides a look-ahead feature because the character remains in the keyboard buffer until function 10h read it.
718
INT 16 h Function 12h : Return Keyboard Flags status
This operation delivers the keyboard status byte from BIOS Data Area 1 at location 40:17h to AL and the byte form 40:18h to AH. Please see Table pp 532
719
Keyboard Operations The keyboard provides three basic types of keys:
Standard characters, which consist of the letters A through Z, numbers 0 through 9, and such characters as 5 , $ and #. Extended function keys, which consist of : - Program function keys, such as F1 and Shift+F1 - Numeric keypad keys with NumLock toggled off: Home, End, Arrows, Del,Ins, PageUp, and PageUp, and the duplicate keys for them on the extended keyboard - Alt+ alphabetic and Alt+ program- function keys. 3. Special keys Alt, Ctr, and Shift, which normally work in association with other keys as well CapsLock, NumLock, and ScrollLock, which indicate a condition
720
BIOS Keyboard data areas
Keyboard Data Area 1 contains two bytes. The first byte is at 40:17H, where bits set to 1 indicate the following: Bit Action 7 Insert active 3 Right Alt pressed 6 CapsLock state active 2 Right Ctrl pressed 5 NumLock state active 1 Left Shift pressed 4 Scroll Lock state active Right Shift pressed
721
Keyboard Data Area 1 For the second byte of Keyboard Data Area 1 at 40:18 bits set to 1 indicate the following Bit Action 7 Insert pressed 3 Ctr/NumLock( pause) active 6 Capslock pressed 2 SysRq pressed 5 NumLock pressed 1 Left Alt pressed 4 Scroll Lock pressed Left Ctrl pressed
722
BIOS Keyboard data areas
Keyboard Data Area 2 at 40:80h is used for the keyboard buffer. Keyboard Data Area 3 at 40:96H Bit 4 , when on , indicates that an enhanced keyboard is installed.
723
INT 10h The DOS function calls allow a key to be read and a character to be displayed but the cursor is difficult to position at a specific location on the screen. The BIOS function calls allow more control over the video display and require less time to execute than the DOS function calls BIOS provides interrupt INT 10h, known as the video interrupt, which gives access to various functions to control video screen Before we place information on the screen we should get the position of the cursor: function 03h reads cursor position (DH=Row, DL=Column, BH=Page #) function 02h sets cursor position (DH=Row, DL=Column, BH=Page #)
724
INT 10h Function 0Fh finds the number of the active page
the page number is returned in the BH register The cursor position assumes that the left hand page column is column 0 progressing across a line to column 79 the row number corresponds to the character line number on the screen, the top line being line 0
725
02h: Setting the Cursor INT 10h function 02h tells BIOS to locate the cursor at a desired row and column. Set AH to 2, set DH to the desired cursor row, set DL to the column, and set BH to the current video page number ( usually 0). The following instructions position the cursor at row 08, column 15. mov ah,02h ; set cursor position mov BH,00 ; Page number 0 mov dh, 08 ; Row 8 mov dl, 15 Column 15 Int 10h To set row and column in DX, you could also use one MOV instruction with an immediate hex value: MOV dx, 080Fh ; row 08, column 15
726
05h: Select Active Page To call this function, set AH to 5 and AL to the desired page number mov ah,5 ;select display page mov al,1 page 1 selected int 10h call BIOS
727
06h: , 07: Scroll Window Up or Down
The term scrolling a window describes moving data on the video display up or down Rows are numbered 0-24 from the top, and columns are numbered 0-79 from the left. A window covering the entire screen would be from 0,0 to 24,79 The input parameters for calling are: AH= 6 to scroll up or 7 to scroll down AL = number of lines to scroll , or 00H for full screen BH=attribute value ( color) CH,CL = Row and column of the upper left window corner DH,DL = Row and column of the lower right window corner Example: Mov ax, 0600h ; ; ah=06 ( scroll up) and al = 00 ( full screen) Mov bh, 71h White background (7) , blue foreground (1) Mov cx, 0000h Upper left row:column Mov dx, 184Fh Lower right row:column Int 10h
728
03h: Get Cursor Position Example
Set AH to 3 and BX to the current video page number . The values returned are: CH= starting scan line CL = Ending scan line DH=Row DL=Column Example mov ah,3 ;get cursor position mov bh,0 ; video page 0 int 10h ;call BIOS mov sabecursor, cx ; save the cursor lines mov current_row, dh ; save the row mov current_col,dl ; save the column
729
Chapter 6 Input/Output
730
Introduction to I/O Interface
732
Basic Input and Output Interfaces
733
Handshaking/Poling: DB25 Example
734
Output 8-bit Data to Port 703 (1010111111B)
736
Input 8-bit Data to Port 703 (1010111111B)
737
Interfacing Circuitry
739
I/O Port Address Decoding
742
8255 programmable peripheral interface (PPI)
744
8255 modes of operation
745
8255 control word
746
Programming 8255: examples
747
8255 handshaking communication
748
8255 handshaking communication (continued)
749
8255 application: A/D conversion
750
8255 application: A/D conversion (continued)
751
Chapter 7 Hardware Interrupts
752
Interrupts
753
Interrupts in 8088
754
Interrupt Vector Table
755
Interrupt Vector Table
756
Allocation of Interrupts in IBM PC/XT
757
Interrupt Instructions: INT, INTO, IRT
758
A Typical Interrupt System of a Microcomputer
759
DOS and BIOS function calls
760
DOS functions: INT 21H
761
DOS functions: INT 21H (cont.)
762
BIOS functions: INT 10H
763
Interrupt-driven I/O versus polled I/O
764
8088 Hardware Interrupts
765
INTR
766
Handling of INTR
767
Priorities of Interrupts
768
8259A Programmable Interrupt Controller
769
8259A Internal Architecture
770
8259A Interfacing
771
8259A Interrupt-Handling Process
772
Cascading Multiple PICs
773
Cascading Multiple PICs: circuit diagram
774
8259A Programming
775
ICW1
776
ICW2
777
Interrupt Types Defined by ICW2
778
ICW3
779
ICW3: example
780
ICW4
781
OCW1, OCW2
782
OCW3
783
Example
784
Example (cont.)
785
Chapter 8 Serial I/O
786
Serial I/O
787
Serial Communication: Terminlology
788
Baud vs. Bit-rate
789
Intel 8251 USART
790
8251 to 8088 asynchronous interface
791
8251 programming: mode instruction byte
792
8251 programming
793
I/O Flow Control
794
RS 232C
795
New Standards: RS-423 & RS-422
796
Chapter 9 DMA
797
Direct Memory Access
798
Basic Process of DMA
799
DMA Controller
800
8237 DMA Controller
801
8237 Interfacing with 8088
802
8237 Interfacing with Peripherals
803
8237 operation
805
8237 Internal Registers (1)
806
8237 Internal Registers (2)
807
8237 Internal Registers (3)
808
Chapter 10 A/D D/A
809
A/D and D/A
810
A/D Converter Fundamentals
811
Connecting digital circuitry to sensor devices is simple if the sensor devices are inherently digital themselves. Switches, relays, and encoders are easily interfaced with gate circuits due to the on/off nature of their signals. However, when analog devices are involved, interfacing becomes much more complex. What is needed is a way to electronically translate analog signals into digital (binary) quantities, and visa-versa. An analog-to-digital converter, or ADC, performs the former task while a digital-to-analog converter, or DAC, performs the latter.
812
An ADC inputs an analog electrical signal such as voltage or current and outputs a binary number. In block diagram form, it can be represented as such: A DAC, on the other hand, inputs a binary number and outputs an analog voltage or current signal. In block diagram form, it looks like this:
813
Together, they are often used in digital systems to provide complete interface with analog sensors and output devices for control systems such as those used in automotive engine controls: It is much easier to convert a digital signal into an analog signal than it is to do the reverse. Therefore, we will begin with DAC circuitry and then move to ADC circuitry
825
D/A and A/D
831
The tipical chip of A/D Converter is ADC0809,which is a 8-Bit uP Compatible A/D Converters with 8-Channel,ADC0809 data acquisition component is a monolithic CMOS device with an 8-bit analog-to-digital converter, 8-channel multiplexer and microprocessor compatible control logic. The 8-bit A/D converter uses successive approximation as the conversion technique. The converter features a high impedance chopper stabilized comparator, a 256R voltage divider with analog switch tree and a successive approximation register. The 8-channel multiplexer can directly access any of 8-single-ended analog signals. The device eliminates the need for external zero and full-scale adjustments. Easy interfacing to microprocessors is provided by the latched and decoded multiplexer address inputs and latched TTL TRI-STATE. outputs. The design of the ADC0808, ADC0809 has been optimized by incorporating the most desirable aspects of several A/D conversion techniques. The ADC0808, ADC0809 offers high speed, high accuracy, minimal temperature dependence, excellent long-term accuracy and repeatability, and consumes minimal power. These features make this device ideally suited to applications from process and machine control to consumer and automotive applications.
834
The tipical chip of D/A Converter is DAC0832,which is a 8-Bit mP Compatible, Double-Buffered D to A Converters. The DAC0832 is an advanced CMOS/Si-Cr 8-bit multiplying DAC designed to interface directly with the 8080, 8048, 8085, Z80……, and other popular microprocessors. A deposited silicon-chromium R-2R resistor ladder network divides the reference current and provides the circuit with excellent temperature tracking characteristics (0.05% of Full Scale Range maximum linearity error over temperature). The circuit uses CMOS current switches and control logic to achieve low power consumption and low output leakage current errors. Special circuitry provides TTL logic input voltage level compatibility. Double buffering allows these DACs to output a voltage corresponding to one digital word while holding the next digital word. This permits the simultaneous updating of any number of DACs. The DAC0832 series are the 8-bit members of a family of microprocessor-compatible DACs (MICRO-DACTM). For applications demanding higher resolution, the DAC1000 series (10-bits) and the DAC1208 and DAC1230 (12-bits) are available alternatives. BI-FETTM and MICRO-DACTM are trademarks of National Semiconductor Corporation.
835
Reference Design
Similar presentations
© 2025 SlidePlayer.com Inc.
All rights reserved.