n n 1 AND ASCII l a 61

  • Slides: 126
Download presentation

(二)布尔和比较指令 n n 1. AND 指令 大写字母与小写字母的 ASCII 码之间的关系: l 'a': 61 h,即 01100001

(二)布尔和比较指令 n n 1. AND 指令 大写字母与小写字母的 ASCII 码之间的关系: l 'a': 61 h,即 01100001 l 'A': 41 h,即 01000001 例:将字符转换位大写形式:. data array BYTE 50 DUP(? ). code mov ecx, LENGTHOF array mov esi, OFFSET array L 1: and byte ptr [esi], 11011111 b inc esi loop L 1 6

(三)条件跳转 3. 条件跳转指令的类型 例: mov al, 7 Fh +127) cmp al, 80 h 128)

(三)条件跳转 3. 条件跳转指令的类型 例: mov al, 7 Fh +127) cmp al, 80 h 128) ja Is. Above jg Is. Greater ; (7 Fh or ; (80 h or ; no: 7 F not > 80 h ; yes: +127 > -128 22

(三)条件跳转 3. 条件跳转指令的类型 例: 8位内存操作数status中存放着同接口卡相连的外设 的状态信息。 1. bit 5为“ 1”时外设处于脱机状态,跳转到某标号处 2. bit 0、bit 1、bit

(三)条件跳转 3. 条件跳转指令的类型 例: 8位内存操作数status中存放着同接口卡相连的外设 的状态信息。 1. bit 5为“ 1”时外设处于脱机状态,跳转到某标号处 2. bit 0、bit 1、bit 4任何一位为“ 1”时跳转到某标号处 3. bit 2、bit 3、bit 7全部为“ 1”时跳转到某标号处 ① mov al, status ③ mov al, status test al, 00100000 b jnz Equip. Offline ② mov and al, 10001100 b cmp al, 10001100 b jz Reset. Machine al, status test al, 00010011 b jnz Input. Data. Byte 23

(三)条件跳转 3. 条件跳转指令的类型 例:比较 V 1、V 2、V 3 三个无符号变量的值,将最小 值送入AX寄存器。. data V 1 WORD

(三)条件跳转 3. 条件跳转指令的类型 例:比较 V 1、V 2、V 3 三个无符号变量的值,将最小 值送入AX寄存器。. data V 1 WORD V 2 WORD V 3 WORD. code mov cmp jbe mov L 1: cmp jbe mov L 2: ? ? ? ax, V 1 ax, V 2 L 1 ax, V 2 ax, V 3 L 2 ax, V 3 ; assume V 1 is smallest ; if ax <= V 2 then ; jump to L 1 ; else move V 2 to ax ; if ax <= V 3 then ; jump to L 2 ; else move V 3 to ax 24

INCLUDE Irvine 32. inc 扫描数组. data Arry. Scan. asm int. Array SWORD 0, 0,

INCLUDE Irvine 32. inc 扫描数组. data Arry. Scan. asm int. Array SWORD 0, 0, 1, 20, 35, -12, 66, 4, 0 none. Msg BYTE "A non-zero value was not found", 0. code main PROC mov ebx, OFFSET int. Array ; point to the array mov ecx, LENGTHOF int. Array ; loop counter L 1: cmp WORD PTR [ebx], 0 ; compare value to zero jnz found ; found a value add ebx, 2 ; point to next loop L 1 ; continue the loop jmp not. Found ; none found: movsx eax, WORD PTR [ebx] ; otherwise, display it call Write. Int jmp quit not. Found: mov edx, OFFSET none. Msg ; display "not found" message call Write. String quit: call crlf exit main ENDP END main

(四)条件循环指令 3. 例子 扫描数组中的每个数值,直到发现正数为止。. data array SWORD -3, -6, -10, 10, 30, 4 sentinel

(四)条件循环指令 3. 例子 扫描数组中的每个数值,直到发现正数为止。. data array SWORD -3, -6, -10, 10, 30, 4 sentinel SWORD 0. code mov esi, OFFSET array mov ecx, LENGTHOF array next: test WORD PTR [esi], 8000 h ; test highest 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 ; SI points to value quit: 29

(五)条件结构 例:以表格驱动的分支选择 D: Masm 615Examplesch 06Proc. Tble. asm INCLUDE Irvine 32. inc. data Case.

(五)条件结构 例:以表格驱动的分支选择 D: Masm 615Examplesch 06Proc. Tble. asm INCLUDE Irvine 32. inc. data Case. Table BYTE 'A' ; lookup value DWORD Process_A ; address of procedure Entry. Size = ($ - Case. Table) BYTE 'B' DWORD Process_B BYTE 'C' DWORD Process_C BYTE 'D' DWORD Process_D Number. Of. Entries = 4 prompt BYTE "Press capital A, B, C, or D: ", 0 msg. A BYTE "Process_A", 0 msg. B BYTE "Process_B", 0 msg. C BYTE "Process_C", 0 msg. D BYTE "Process_D", 0 31

(五)条件结构. code main PROC mov call mov L 1: cmp jne call jmp L

(五)条件结构. code main PROC mov call mov L 1: cmp jne call jmp L 2: add loop L 3: exit main ENDP 例:以表格驱动的分支选择 Process_A PROC mov edx, OFFSET msg. A ret Process_A ENDP ; ask user for input edx, OFFSET prompt Write. String Process_B PROC Read. Char ; read one character mov edx, OFFSET msg. B ebx, OFFSET Case. Table ; point EBX to the table ret ecx, Number. Of. Entries ; loop counter Process_B ENDP al, [ebx] ; match found? L 2 ; no: continue Process_C PROC NEAR PTR [ebx + 1] ; yes: call the procedure mov edx, OFFSET msg. C Write. String ; display message ret Crlf Process_C ENDP L 3 ; exit the search ebx, Entry. Size ; point to the next entry (+5) Process_D PROC L 1 ; repeat until ECX = 0 mov edx, OFFSET msg. D ret Process_D ENDP END main 32

(一)移位和循环移位指令 6. ROR指令:循环右移 · · · · CF 例: mov al, 01 h ror

(一)移位和循环移位指令 6. ROR指令:循环右移 · · · · CF 例: mov al, 01 h ror al, 1 ; 00000001 ; 10000000, CF=1 ; 01000000, CF=0 42

(一)移位和循环移位指令 7. RCL指令和RCR指令 n RCL指令:带进位的循环左移 CF · n · · · · RCR指令:带进位的循环右移 ·

(一)移位和循环移位指令 7. RCL指令和RCR指令 n RCL指令:带进位的循环左移 CF · n · · · · RCR指令:带进位的循环右移 · · · · n CF · 例:从进位标志中恢复一个位。. data testval BYTE 01101010 b. code shr testval, 1 ; shift LSB into Carry flag jc quit ; exit if Carry flag set rcl testval, 1 ; else restore the number 43

(一)移位和循环移位指令 n 例1:. data wval WORD 9 BA 6 h. code mov ax, 0

(一)移位和循环移位指令 n 例1:. data wval WORD 9 BA 6 h. code mov ax, 0 AC 36 h shld wval, ax, 4 n 8. SHLD/SHRD指令 例2: mov ax, 234 Bh mov dx, 7654 h shrd ax, dx, 4 wval 9 BA 6 AX AC 36 BA 6 A AC 36 DX 7654 AX 234 B 7654 4234 45

(一)移位和循环移位指令 9. 移位和循环移位的应用 n n 多双字移位 二进制乘法 显示二进制位 分离位串 99999999 h [esi+8] [esi+4] [esi].

(一)移位和循环移位指令 9. 移位和循环移位的应用 n n 多双字移位 二进制乘法 显示二进制位 分离位串 99999999 h [esi+8] [esi+4] [esi]. data Array. Size = 3 array DWORD Array. Size DUP(9999 h). code mov esi, 0 shr array[esi+8], 1 rcr array[esi+4], 1 rcr array[esi], 1 47

(二)乘法和除法指令 n 1. MUL指令 例: mov al, 5 h mov bl, 10 h mul

(二)乘法和除法指令 n 1. MUL指令 例: mov al, 5 h mov bl, 10 h mul bl ; 积在AX中,50 h ; CF = 0 . data val 1 WORD 2000 h val 2 WORD 0100 h. code mov ax, val 1 mul val 2 ; CF = 1 ; 积在DX: AX中,00200000 h 50

(二)乘法和除法指令 n n n 2. IMUL指令 有符号乘法,格式与MUL指令相同。 如果积的高半部分不是低半部分的符号扩展,则设 置CF和OF。 例: mov al, 48 ;

(二)乘法和除法指令 n n n 2. IMUL指令 有符号乘法,格式与MUL指令相同。 如果积的高半部分不是低半部分的符号扩展,则设 置CF和OF。 例: mov al, 48 ; 48 D = 30 H mov bl, 4 imul bl ; AX = 00 C 0 h, OF = 1 mov al, -4 mov bl, 4 imul bl ; AX = FFF 0 h, OF = 0 mov ax, 48 mov bx, 4 imul bx ; DX: AX = 000000 C 0 h, OF = 0 51

3. DIV指令 (二)乘法和除法指令 n 例: ; 8003 h/100 h mov dx, 0 mov ax,

3. DIV指令 (二)乘法和除法指令 n 例: ; 8003 h/100 h mov dx, 0 mov ax, 8003 h mov cx, 100 h div cx ; ; clear dividend, high dividend, low divisor AX = 0080 h, DX = 0003 h . data dividend QWORD 0000000800300020 h divisor DWORD 00000100 h. code mov edx, DWORD PTR dividend + 4 ; high doubleword mov eax, DWORD PTR dividend ; low doubleword divisor ; EAX = 08003000 h, EDX = 00000020 h 53

(二)乘法和除法指令 4. 有符号整数除法 ① CBW,CWD 和 CDQ 指令 n CBW(Convert Byte to Word) 将AL中的符号位扩展到AH寄存器中。

(二)乘法和除法指令 4. 有符号整数除法 ① CBW,CWD 和 CDQ 指令 n CBW(Convert Byte to Word) 将AL中的符号位扩展到AH寄存器中。 n CWD(Convert Word to Doubleword) 将AX的符号位扩展到DX寄存器中。 n CDQ(Convert Doubleword to Quadword) 将EAX中的符号位扩展到EDX寄存器中。 n 例:. data word. Val SWORD -101. code mov ax, word. Val cwd ; FF 9 Bh ; AX = FF 9 Bh ; DX: AX = FFFFFF 9 Bh 54

4. 有符号整数除法 (二)乘法和除法指令 ② IDIV 指令 n 例:. data byte. Val SBYTE -48. code

4. 有符号整数除法 (二)乘法和除法指令 ② IDIV 指令 n 例:. data byte. Val SBYTE -48. code mov al, byte. Val cbw mov bl, 5 idiv bl . data word. Val SWORD -5000. code mov ax, word. Val cwd mov bx, 256 idiv bx ; ; ; ; ; dividend extend AL into AH divisor AL = -9, AH = -3 dividend, extend AX divisor quotient remainder low into DX AX = -19 DX = -136 56

(二)乘法和除法指令 5. 算数表达式的实现 【例1】以汇编语言实现下面的C++语句(使用 32位无 符号整数): var 4 = (var 1 + var 2)

(二)乘法和除法指令 5. 算数表达式的实现 【例1】以汇编语言实现下面的C++语句(使用 32位无 符号整数): var 4 = (var 1 + var 2) * var 3; mov eax, var 1 add eax, var 2 mul var 3 jc too. Big mov var 4, eax jmp next too. Big: ; EAX = EAX * var 3 ; unsigned overflow? ; display error message 59

(二)乘法和除法指令 5. 算数表达式的实现 【例2】使用 32位有符号整数实现下面C++语句: var 4 = (var 1 * -5) / (-var

(二)乘法和除法指令 5. 算数表达式的实现 【例2】使用 32位有符号整数实现下面C++语句: var 4 = (var 1 * -5) / (-var 2 % var 3); mov eax, var 2 ; begin right side neg eax ; 有符号数, 需将被除数符号扩展到EDX, 然后用IDIV指令 cdq ; sign-extend dividend idiv var 3 ; EDX = remainder mov ebx, edx ; EBX = right side mov eax, -5 imul var 1 ; begin left side ; EDX: EAX = left side idiv ebx mov var 4, eax ; final division ; quotient 60

(三)扩展加法和减法 n n n 1. ADC指令 功能:add with carry,扩展加法。 目的操作数+源操作数+进位标志→目的操作数 格式:同MOV指令。 ADC reg, reg

(三)扩展加法和减法 n n n 1. ADC指令 功能:add with carry,扩展加法。 目的操作数+源操作数+进位标志→目的操作数 格式:同MOV指令。 ADC reg, reg ADC mem, reg ADC reg, mem ADC mem, imm ADC reg, imm 扩展加法的例子 D: Masm 615Examplesch 07Ext. Add. asm 62

; ---------------------------Extended_Add PROC ; ; Calculates the sum of two extended integers that are

; ---------------------------Extended_Add PROC ; ; Calculates the sum of two extended integers that are ; stored as an array of doublewords. ; Receives: ESI and EDI point to the two integers, ; EBX points to a variable that will hold the sum, and ; ECX indicates the number of doublewords to be added. ; ---------------------------pushad clc ; clear the Carry flag L 1: mov eax, [esi] ; get the first integer adc eax, [edi] ; add the second integer pushfd ; save the Carry flag mov [ebx], eax ; store partial sum add esi, 4 ; advance all 3 pointers add edi, 4 add ebx, 4 popfd ; restore the Carry flag loop L 1 ; repeat the loop adc word ptr [ebx], 0 ; add any leftover carry popad ret Extended_Add ENDP ② 子程序 END main

TITLE Extended Addition Example (Ext. Add. asm) ; This program calculates the sum of

TITLE Extended Addition Example (Ext. Add. asm) ; This program calculates the sum of two 64 -bit integers. INCLUDE Irvine 16. inc. data op 1 QWORD 0 A 2 B 2 A 40674981234 h op 2 QWORD 08010870000234502 h sum DWORD 3 dup(0). code main PROC mov ax, @data mov ds, ax mov mov call exit main ENDP esi, OFFSET op 1 edi, OFFSET op 2 ebx, OFFSET sum ecx, 2 Extended_Add esi, OFFSET sum ebx, 4 ecx, 3 Dump. Mem ; ; first operand second operand sum operand number of doublewords ; dump memory ; is doublewords ; three doublewords ① 主程序

(四)ASCII和压缩十进制算数 n n 1. AAA指令 功能:ASCII adjust after addition 调整两个ASCII数字用ADD或ADC指令相加之后在 AL中的结果。 例: mov ah,

(四)ASCII和压缩十进制算数 n n 1. AAA指令 功能:ASCII adjust after addition 调整两个ASCII数字用ADD或ADC指令相加之后在 AL中的结果。 例: mov ah, 0 mov al, '8' ; AX = 0038 h add al, '2' ; AX = 006 Ah aaa ; AX = 0100 h or ax, 3030 h ; AX = 3130 h = '10' 67

(四)ASCII和压缩十进制算数 2. AAS指令 n 功能:ASCII adjust after subtraction 调整ASCII减法之后AL中得到的结果。 仅当减法产生负数结果时调整才是必须的。 n 例:. data val

(四)ASCII和压缩十进制算数 2. AAS指令 n 功能:ASCII adjust after subtraction 调整ASCII减法之后AL中得到的结果。 仅当减法产生负数结果时调整才是必须的。 n 例:. data val 1 BYTE '8' val 2 BYTE '9'. code mov ah, 0 mov al, val 1 sub al, val 2 aas pushf or al, 30 h popf ; ; ; AX = 0038 h AX = 00 FFh AX = FF 09 h save the Carry flag AX = FF 39 h restore the Carry flag 68

(四)ASCII和压缩十进制算数 n n 3. AAM指令 功能:ASCII adjust after multiplication 调整两个未压缩的BCD数字相乘之后AX中的结果, 即将二进制值调整为非压缩的ASCII格式。 例:. data Asc.

(四)ASCII和压缩十进制算数 n n 3. AAM指令 功能:ASCII adjust after multiplication 调整两个未压缩的BCD数字相乘之后AX中的结果, 即将二进制值调整为非压缩的ASCII格式。 例:. data Asc. Val BYTE 05 h, 06 h. code mov bl, Asc. Val ; first operand mov al, Asc. Val+1 ; second operand mul bl ; AX = 001 Eh aam ; AX = 0300 h 69

(四)ASCII和压缩十进制算数 n n 4. AAD指令 功能:ASCII adjust before division 将AH和AL中未压缩的BCD数字转换成二进制数值 存放在AL中,AH清零,为DIV指令做好准备。 例:. data quotient

(四)ASCII和压缩十进制算数 n n 4. AAD指令 功能:ASCII adjust before division 将AH和AL中未压缩的BCD数字转换成二进制数值 存放在AL中,AH清零,为DIV指令做好准备。 例:. data quotient BYTE ? remainder BYTE ? . code mov ax, 0307 h aad mov bl, 5 div bl mov quotient, al mov remainder, ah ; ; ; dividend AX = 0025 h divisor AX = 0207 h 37/5,商为 7,余数 2 70

(一)堆栈参数 n 寄存器参数:寄存器内容在装入参数前必须保存。 pushad mov esi, OFFSET array mov ecx, LENGTHOF array mov ebx,

(一)堆栈参数 n 寄存器参数:寄存器内容在装入参数前必须保存。 pushad mov esi, OFFSET array mov ecx, LENGTHOF array mov ebx, TYPE array call Dump. Mem popad n starting OFFSET size, in units doubleword format display memory 堆栈参数:需要的参数由调用程序压入堆栈。 push call n ; ; OFFSET array LENGTHOF array TYPE array Dump. Mem 使用INVOKE伪指令可自动在堆栈上压入参数并调用 程序。 INVOKE Dump. Mem, TYPE array, LENGTHOF array, OFFSET array n 几乎所有高级语言都使用堆栈参数。 73

; Demonstration of the Swap procedure, using ; PROTO, PROC, and INVOKE. INCLUDE Irvine

; Demonstration of the Swap procedure, using ; PROTO, PROC, and INVOKE. INCLUDE Irvine 32. inc Swap PROTO, ; procedure prototype p. Val. X: PTR DWORD, p. Val. Y: PTR DWORD. data Array DWORD 10000 h, 20000 h. code main PROC ; Display the array before the exchange: mov esi, OFFSET Array mov ecx, 2 ; count = 2 mov ebx, TYPE Array call Dump. Mem ; dump the array values INVOKE Swap, ADDR Array, ADDR [Array+4] ; Display the array after the exchange: call Dump. Mem exit main ENDP

; ---------------------------Swap PROC USES eax esi edi, p. Val. X: PTR DWORD, ; pointer

; ---------------------------Swap PROC USES eax esi edi, p. Val. X: PTR DWORD, ; pointer to first integer p. Val. Y: PTR DWORD ; pointer to second integer ; ; Exchange the values of two 32 -bit integers ; Returns: nothing ; ---------------------------mov esi, p. Val. X ; get pointers mov edi, p. Val. Y mov eax, [esi] ; get first integer xchg eax, [edi] ; exchange with second mov [esi], eax ; replace first integer ret Swap ENDP END main

(二)堆栈框架 n 堆栈参数的显式访问. data sum DWORD ? . code push 6 push 5 call

(二)堆栈框架 n 堆栈参数的显式访问. data sum DWORD ? . code push 6 push 5 call Add. Two mov sum, eax …… Add. Two push mov add pop ret Add. Two ; ; second argument first argument EAX = sum save the sum PROC ebp, esp eax, [ebp + 12] eax, [ebp + 8] ebp 8 ENDP EBP, ESP 返回地址 00000005 00000006 [EBP+4] [EBP+8] [EBP+12] ; base of stack frame ; second argument ; first argument ; clean up the stack 78

(二)堆栈框架 n 传递引用(即变量的地址)参数. data count = 100 array WORD count DUP(? ). code push

(二)堆栈框架 n 传递引用(即变量的地址)参数. data count = 100 array WORD count DUP(? ). code push OFFSET array push COUNT call Array. Fill ESP …… EBP 返回地址 count offset(array) EBP , ESP [EBP+4] [EBP+8] [EBP+12] L 1: mov eax, 10000 h ; get random 0 -FFFFh Array. Fill PROC call Random. Range ; from the link lib push ebp mov [esi], eax mov ebp, esp add esi, TYPE WORD pushad loop L 1 mov esi, [ebp+12] ; offset of array popad mov ecx, [ebp+8] L 2: ; array size pop cmp ecx, 0 ; ECX <= ebp 0 ? ret skip 8 over loop ; clean up the stack jle L 2 ; yes: Array. Fill ENDP 79

(二)堆栈框架 n LEA指令:计算并装入内存操作数的偏移。 指令格式:LEA reg, mem 【例】 Fill. String PROC USES eax esi LOCAL

(二)堆栈框架 n LEA指令:计算并装入内存操作数的偏移。 指令格式:LEA reg, mem 【例】 Fill. String PROC USES eax esi LOCAL string[20]: BYTE ; mov esi, OFFSET string ; error lea esi, string mov ecx, 20 L 1: mov eax, 10 call Random. Range ; AL = 0. . 9 add al, 30 h mov [esi], al add esi, 1 Loop L 1 LOCAL伪指令在过程中声明 ret 一个或多个局部变量。 Fill. String ENDP 80

(二)堆栈框架 n 创建局部变量 l C++ 例子 l 用汇编语言实现 ESP [EBP-36] Z void My. Sub()

(二)堆栈框架 n 创建局部变量 l C++ 例子 l 用汇编语言实现 ESP [EBP-36] Z void My. Sub() { char X = 'X'; int Y = 10; char name[20]; name[0] = 'B' double Z = 1. 2; } [EBP-28] name …… Y X EBP [EBP-8] 返回地址 [EBP+4] [EBP-4] EBP 变量 X Y name 字节数 4 4 20 堆栈偏移 EBP-4 EBP-8 EBP-28 Z 8 EBP-36 81

(二)堆栈框架 n 创建局部变量 l 用汇编语言实现 My. Sub PROC push ebp mov ebp, esp sub

(二)堆栈框架 n 创建局部变量 l 用汇编语言实现 My. Sub PROC push ebp mov ebp, esp sub esp, 36 mov mov mov ESP [EBP-36] Z [EBP-28] name 汇编 …… Y X EBP [EBP-8] 返回地址 [EBP+4] [EBP-4] EBP ; create variables BYTE PTR [ebp-4], 'X' ; X DWORD PTR [ebp-8], 10 ; Y C++ BYTE PTR [ebp-28], 'B' ; void name[0] My. Sub() DWORD PTR [ebp-32], 3 ff 33333 h ; {Z(high) DWORD PTR [ebp-36], 3333 h ; Z(low) char X = 'X'; mov esp, ebp pop ebp ret My. Sub ENDP int Y = 10; ; destroy variables char name[20]; name[0] = 'B' double Z = 1. 2; } 82

(一)基本字符串操作指令 1. MOVSB、MOVSW 和 MOVSD 指令 例:. data source DWORD 20 DUP(0 FFFFh) target

(一)基本字符串操作指令 1. MOVSB、MOVSW 和 MOVSD 指令 例:. data source DWORD 20 DUP(0 FFFFh) target DWORD 20 DUP(? ). code cld ; mov ecx, LENGTHOF source ; mov esi, OFFSET source ; mov edi, OFFSET target ; rep movsd ; direction = forward set REP counter ESI points to source EDI points to target copy doublewords 91

(一)基本字符串操作指令 2. CMPSB、CMPSW 和 CMPSD 指令 隐含执行:源-目的,这与 CMP 指令相反。 例: mov cld mov repe

(一)基本字符串操作指令 2. CMPSB、CMPSW 和 CMPSD 指令 隐含执行:源-目的,这与 CMP 指令相反。 例: mov cld mov repe esi, OFFSET source edi, OFFSET target ecx, count cmpsd ; direction = up ; repetition counter ; repeat while equal 92

INCLUDE Irvine 32. inc. data source BYTE "MARTIN " dest BYTE "MARTINEZ" str 1

INCLUDE Irvine 32. inc. data source BYTE "MARTIN " dest BYTE "MARTINEZ" str 1 BYTE "Source is smaller", 0 dh, 0 ah, 0 str 2 BYTE "Source is not smaller", 0 dh, 0 ah, 0. code main PROC cld ; direction = up mov esi, OFFSET source mov edi, OFFSET dest mov cx, LENGTHOF source repe cmpsb jb source_smaller mov edx, OFFSET str 2 jmp done source_smaller: mov edx, OFFSET str 1 done: call Write. String exit main ENDP END main

(一)基本字符串操作指令 3. SCASB、SCASW 和 SCASD 指令 将AL/AX/EAX中的值同目标内存(由DI寻址)中的字节、 字或双字相比较。 【例】扫描一个匹配字符:在字符串变量alpha中查找字母“F”。. data alpha BYTE "ABCDEFGH", 0.

(一)基本字符串操作指令 3. SCASB、SCASW 和 SCASD 指令 将AL/AX/EAX中的值同目标内存(由DI寻址)中的字节、 字或双字相比较。 【例】扫描一个匹配字符:在字符串变量alpha中查找字母“F”。. data alpha BYTE "ABCDEFGH", 0. code mov edi, OFFSET alpha mov al, 'F' mov ecx, LENGTHOF alpha cld repne scasb jnz quit dec edi quit: ; ; ; ; EDI points to the string search for the letter F set the search count direction = up repeat while not equal quit if letter not found: back up EDI 95

(一)基本字符串操作指令 4. STOSB、STOSW 和 STOSD 指令 将AL/AX/EAX的内容存储在EDI指向的内存单元中, 同时EDI的值根据方向标志增加或减少。可与REP前 缀联合使用。 例:将string 1的每个字节初始化为 0 FFh。. data

(一)基本字符串操作指令 4. STOSB、STOSW 和 STOSD 指令 将AL/AX/EAX的内容存储在EDI指向的内存单元中, 同时EDI的值根据方向标志增加或减少。可与REP前 缀联合使用。 例:将string 1的每个字节初始化为 0 FFh。. data count = 100 string 1 BYTE count DUP(? ). code mov al, 0 FFh mov edi, OFFSET string 1 mov ecx, count cld rep stosb ; ; ; value to be stored ES: DI points to target character count direction = forward fill with contents of AL 96

TITLE Multiply an Array (Mult. asm) ; This program multiplies each element of an

TITLE Multiply an Array (Mult. asm) ; This program multiplies each element of an array ; of 32 -bit integers by a constant value. INCLUDE Irvine 32. inc. data array DWORD 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ; test data multiplier DWORD 10 ; test data. code main PROC cld ; direction = up mov esi, OFFSET array ; source index mov edi, esi ; destination index mov ecx, LENGTHOF array ; loop counter L 1: lodsd ; copy [ESI] into EAX multiplier ; multiply by a value stosd ; store EAX at [EDI] loop L 1 exit main ENDP END main

(二)二维数组 n 表格的例子。 1. 基址变址操作数 . data 0 1 2 3 4 table. B

(二)二维数组 n 表格的例子。 1. 基址变址操作数 . data 0 1 2 3 4 table. B BYTE 0 10 h, 20 h, 30 h, 40 h, 50 h 列 BYTE 1 60 h, 70 h, 80 h, 90 h, 0 A 0 h BYTE 2 0 B 0 h, 0 C 0 h, 0 D 0 h, 0 E 0 h, 0 F 0 h Num. Cols = 5 行. code Row. Number = 1 ; 第 1行 Column. Number = 2 ; 第 2列 mov ebx, OFFSET table. B add ebx, Num. Cols*Row. Number mov esi, Column. Number mov al, [ebx+esi] ; AL = 80 h 第 0行 第 1行 第 2行 10 20 30 40 50 60 70 80 90 A 0 B 0 C 0 D 0 E 0 F 0 table. B [EBX] [EBX+ESI] 100

(二)二维数组 n 表格的例子: 2. 相对基址变址操作数 . data 0 1 2 3 4 table. B

(二)二维数组 n 表格的例子: 2. 相对基址变址操作数 . data 0 1 2 3 4 table. B BYTE 0 10 h, 20 h, 30 h, 40 h, 50 h 列 BYTE 1 60 h, 70 h, 80 h, 90 h, 0 A 0 h BYTE 2 0 B 0 h, 0 C 0 h, 0 D 0 h, 0 E 0 h, 0 F 0 h Num. Cols = 5 行. code Row. Number = 1 ; 第 1行 Column. Number = 2 ; 第 2列 mov ebx, Num. Cols*Row. Number ; 第 1行起始地址: 5× 1 mov esi, Column. Number ; 列号: 2 mov al, table. B[ebx+esi] ; AL = 80 h 第 0行 第 1行 第 2行 10 20 30 40 50 60 70 80 90 A 0 B 0 C 0 D 0 E 0 F 0 table. B[EBX] table. B[EBX+ESI] 102

(一)结构 2. 结构的声明及引用 声明 Employee STRUCT Id. Num BYTE Last. Name BYTE Years WORD

(一)结构 2. 结构的声明及引用 声明 Employee STRUCT Id. Num BYTE Last. Name BYTE Years WORD Salary. History Employee ENDS . data worker Employee <> person 1 Employee <” 555223333”> person 2 Employee <, ”Jones”> person 3 Employee <, , , 2 DUP(20000)> ” 00000” 30 DUP(0) 0 DWORD 0, 0, 0, 0 定义 引用 . code mov dx, worker. Years mov worker. Salary. History+4, 30000 ; second salary mov edx, OFFSET worker. Last. Name mov esi, OFFSET worker mov ax, (Employee PTR [esi]). Years 106

(二)宏 【例1】 m. Write. Str MACRO string push edx mov edx, OFFSET string call

(二)宏 【例1】 m. Write. Str MACRO string push edx mov edx, OFFSET string call Write. String pop edx 定义 ENDM 编译后的代码 push edx mov edx, OFFSET msg 1 call Write. String pop edx push edx mov edx, OFFSET msg 2. data call Write. String msg 1 BYTE ”This is message 1. ”, 0 Dh, 0 Ah, ’$’ pop edx msg 2 BYTE ”This is message 2. ”, 0 Dh, 0 Ah, ’$’ push edx msg 3 BYTE ”This is message 3. ”, 0 Dh, 0 Ah, ’$’ mov edx, OFFSET msg 3. code call Write. String m. Write. Str msg 1 pop edx m. Write. Str msg 2 m. Write. Str msg 3 调用 108

(二)宏 【例2】 HTOASC MACRO LOCAL ISDECM AND AL, 0 FH CMP AL, 9 JBE

(二)宏 【例2】 HTOASC MACRO LOCAL ISDECM AND AL, 0 FH CMP AL, 9 JBE ISDECM ADD AL, 7 ISDECM: ADD AL, 30 H ENDM. . . HTOASC. . . 调用 定义 编译后的代码. . . AND AL, 0 FH CMP AL, 9 JBE ? ? 0000 ADD AL, 7 ? ? 0000: ADD AL, 30 H. . . AND AL, 0 FH CMP AL, 9 JBE ? ? 0001 ADD AL, 7 ? ? 0001: ADD AL, 30 H. . . 109

使用I/O端口控制硬件 (二)IN 和 OUT 指令 例: in out mov in out al, 3 Ch,

使用I/O端口控制硬件 (二)IN 和 OUT 指令 例: in out mov in out al, 3 Ch, al dx, 2 A 3 Ch ax, dx dx, ax eax, dx dx, eax ; ; ; ; input byte from port 003 Ch output byte to port 003 Ch DX can contain a port number input word from port named in DX output word to the same port input doubleword from port output doubleword to same port 116

; This program plays a series of ascending notes on ; the PC speaker.

; This program plays a series of ascending notes on ; the PC speaker. . model small, stdcall ; 16 -bit Real mode program. stack 4096 speaker timer delay 1 delay 2 start. Pitch. code main PROC in push or out mov = = = 61 h 42 h 800 7600 ; address of speaker port ; address of timer port ; delay between notes al, speaker ax al, 00000011 b speaker, al ; get speaker status ; save status ; set lowest 2 bits ; turn speaker on bx, start. Pitch ; starting pitch 119

L 2: mov out al, bl timer, al al, bh timer, al ; ;

L 2: mov out al, bl timer, al al, bh timer, al ; ; bit 7. . 0 timer port: pulses speaker bit 15. . 8 timer port: pulses speaker ; Create a delay loop between pitches: mov cx, delay 1 L 3 a: push cx mov cx, delay 2 L 3 b: loop L 3 b pop cx loop L 3 a sub jnz bx, 200 L 2 ; raise pitch ; play another note pop and out ax al, 11111100 b speaker, al ; get original status ; clear lowest 2 bits ; turn speaker off mov ax, 4 c 00 h int 21 h main ENDP END main 120

使用I/O端口控制硬件 (三)例子 2:实时钟 RTC 时钟与日历寄存器组: Address 00 01 02 03 04 05 06 07

使用I/O端口控制硬件 (三)例子 2:实时钟 RTC 时钟与日历寄存器组: Address 00 01 02 03 04 05 06 07 08 09 Function Current second for RTC Alarm second Current minute Alarm minute Current hour Alarm hour Current day of week(01=Sunday) Current date of month Current year(final two digits,eg: 93) 秒 分 时 星期 日 月 年 122

程序功能:显示当前时间。 显示格式:hh: mm: ss, yyyy-mm-dd, week. MODEL small, stdcall. STACK 4096. data ; 01234567890123456789

程序功能:显示当前时间。 显示格式:hh: mm: ss, yyyy-mm-dd, week. MODEL small, stdcall. STACK 4096. data ; 01234567890123456789 weekinfo byte 'Sunday Monday Tuesday Wednesday ' ; 01234567890123456789 byte 'Thursday Friday Saturday ' display byte 0 dh, 0 ah hour byte '00: ' minute byte '00: ' second byte '00, ' year 1 byte '20' year 2 byte '00 -' month byte '00 -' day byte '00, ' week byte 10 dup(20 h), 0 dh, 0 ah, '$' 125

m. Read. RTC mov out nop in ENDM MACRO address al, address 70 h,

m. Read. RTC mov out nop in ENDM MACRO address al, address 70 h, al ; 宏,读地址为address的RTC寄存器 al, 71 h ; 读入数据在al寄存器 m. Trans. Info MACRO string mov string+1, al and string+1, 0 fh add string+1, '0' mov cl, 4 shr al, cl and al, 0 fh add al, '0' mov string, al ENDM ; 送地址 ; 延时 宏 ; 宏,将al中的bcd数据转换为ascii码字符 ; 处理低4位(个位) ; 处理高 4位(十位) ; 转换好的字符(2个)在string中 126

. code main PROC mov ax, @data mov ds, ax mov es, ax m.

. code main PROC mov ax, @data mov ds, ax mov es, ax m. Read. RTC 4 m. Trans. Info hour ; read hour to al ; trans hour to ascii m. Read. RTC 2 m. Trans. Info minute ; read minute to al ; trans minute to ascii m. Read. RTC 0 m. Trans. Info second ; read second to al ; trans second to ascii m. Read. RTC 9 m. Trans. Info year 2 ; read year to al ; trans year to ascii m. Read. RTC 8 m. Trans. Info month ; read month to al ; trans month to ascii m. Read. RTC 7 m. Trans. Info day ; read day to al ; trans day to ascii 127

m. Read. RTC 6 ; read week to al, 01=Sunday dec al ; al:

m. Read. RTC 6 ; read week to al, 01=Sunday dec al ; al: 0, 1, 2, 3, 4, 5, 6 -> Sundy, Monday, . . . , Friday, Saturday mov cx, 10 mul cl ; ax=al*10 mov si, offset weekinfo add si, ax mov di, offset week cld rep movsb ; copy weekinfo string to week mov ah, 9 mov dx, offset display ; display time, date and week int 21 h mov ah, 4 ch int 21 h main ENDP END main 128

数据段: weekinfo+10 weekinfo+20 weekinfo+30 weekinfo+40 weekinfo+50 weekinfo+60 hour Sund Mo n d Tu e

数据段: weekinfo+10 weekinfo+20 weekinfo+30 weekinfo+40 weekinfo+50 weekinfo+60 hour Sund Mo n d Tu e s We d n Thu r Fr i d Sa t u second a a d e s a r y y a s d y day ay ay year 2 day ←↓ 0 0 : 0 0 , 2 0 0 0 - 0 0 , display minute year 1 month ←↓ $ week 129