《汇编语言 基于x86处理器》第九章字符串与数组部分的代码

▶ 书中第九章的程序,主要讲了

● 代码,Irvine32 中的字符串库函数代码范例

 1 INCLUDE Irvine32.inc
 2 
 3 .data
 4 str1    BYTE "abcde////", 0
 5 str2    BYTE "ABCDE", 0
 6 msg0    BYTE "Upper case: ", 0
 7 msg1    BYTE "str1 == str2", 0
 8 msg2    BYTE "str1 < str2", 0
 9 msg3    BYTE "str1 > str2", 0
10 msg4    BYTE "Length of str1: ", 0
11 msg5    BYTE "Trimming: ", 0
12 
13 .code
14 main PROC
15     mov     edx, OFFSET str1
16     call    WriteString
17     call    crlf
18 
19     call    trim_string
20     call    upper_case
21     call    compare_strings
22     call    print_length
23     call    waitmsg
24     exit
25 main ENDP
26 
27 trim_string PROC                        ; 去掉结尾的指定字符
28     INVOKE  Str_trim, ADDR str1, '/'
29     mov     edx, OFFSET msg5
30     call    WriteString
31     mov     edx, OFFSET str1
32     call    WriteString
33     call    Crlf
34     ret
35 trim_string ENDP
36 
37 upper_case PROC                         ; 小写转大写
38     mov     edx, OFFSET msg0
39     call    WriteString
40     INVOKE  Str_ucase, ADDR str1
41     mov     edx, OFFSET str1
42     call    WriteString
43     call    Crlf
44     ret
45 upper_case ENDP
46 
47 compare_strings PROC                    ; 比较 str1 和 str2
48     INVOKE Str_compare, ADDR str1, ADDR str2
49     .IF ZERO?
50     mov     edx, OFFSET msg1     ; str1 = str2
51     .ELSEIF CARRY?
52     mov     edx, OFFSET msg2     ; str1 < str2
53     .ELSE
54     mov     edx, OFFSET msg3     ; str1 > str2
55     .ENDIF
56     call    WriteString
57     call    Crlf
58     ret
59 compare_strings  ENDP
60 
61 print_length PROC                       ; 获取字符串长度
62     mov     edx, OFFSET msg4
63     call    WriteString
64     INVOKE  Str_length, ADDR str1
65     call    WriteDec
66     call    Crlf
67     ret
68 print_length ENDP
69 
70 END main

■ 输出结果

abcde////
Trimming: abcde
Upper case: ABCDE
str1 == str2
Length of str1: 5

● 二维表下标引用

 1 INCLUDE Irvine32.inc
 2 
 3 .data
 4 tableB  BYTE   10h,   20h,   30h,   40h,   50h  ; 数组定义能断开,中间插入一个用于计算数组行宽的常量
 5 Rowsize = ($ - tableB)
 6         BYTE   60h,   70h,   80h,   90h,  0A0h
 7         BYTE  0B0h,  0C0h,  0D0h,  0E0h,  0F0h
 8 
 9 tableW  WORD   10h,   20h,   30h,   40h,   50h
10 RowsizeW = ($ - tableW)
11         WORD   60h,   70h,   80h,   90h,  0A0h
12         WORD  0B0h,  0C0h,  0D0h,  0E0h,  0F0h
13         
14 tableD  DWORD 10000h,    20000h,   30000h,   40000h,   50000h
15 RowSizeD = ($ - tableD)
16         DWORD 60000h,    70000h,   80000h,   90000h,  0A0000h
17         DWORD 0B0000h,  0C0000h,  0D0000h,  0E0000h,  0F0000h
18         
19 .code
20 main PROC
21 
22 row = 1                                 ; 目标元素的下标
23 col = 2
24 
25     mov     ebx, OFFSET tableB          ; 指向数组首元素
26     add     ebx, RowSize * row          ; 计算行偏移
27     mov     esi, col                    ; 列偏移
28     mov     al, [ebx + esi]             ; 取目标元素
29     call    DumpRegs                    ; AL = 80h
30 
31     mov     ebx, OFFSET tableW          ; 相同的过程
32     add     ebx, RowSizeW * row        
33     mov     esi, col
34     mov     ax, [ebx + esi*TYPE tableW] ; 元素不是 BYTE 时要乘以比例因子
35     call    DumpRegs                    ; AX = 0080h
36     
37     mov     eax, row
38     mov     esi, col
39     call    get_tableDval               ; 使用函数寻找目标元素
40     call    WriteHex                    ; 目标元素在 eax 中
41     call    Crlf
42     call    WaitMsg
43     exit
44 main ENDP
45 
46 get_tableDval PROC uses ebx
47     mov    ebx, RowSizeD
48     mul    ebx                                  ; eax *= RowSizeD,行偏移
49     mov    eax, tableD[eax + esi*TYPE tableD]   ; 加上列偏移再寻址
50     ret                                         ; eax = 80000h
51 get_tableDval ENDP
52 
53 END main

● 代码,冒泡排序,二分搜索

 1 ; BinarySearchTest.asm,测试函数
 2 INCLUDE Irvine32.inc
 3 INCLUDE BinarySearch.inc
 4 
 5 LOWVAL = -5000            
 6 HIGHVAL = +5000        
 7 ARRAY_SIZE = 50        
 8 
 9 .data
10 array DWORD ARRAY_SIZE DUP(?)
11 
12 .code
13 main PROC
14     call    Randomize                                           ; 初始化随机数种子
15     INVOKE  FillArray, ADDR array, ARRAY_SIZE, LOWVAL, HIGHVAL  ; 用随机数填充数组    
16     INVOKE  PrintArray, ADDR array, ARRAY_SIZE                  ; 显示数组内容
17     call    WaitMsg
18     call    Crlf
19     
20     INVOKE  BubbleSort, ADDR array, ARRAY_SIZE          ; 冒泡排序
21     INVOKE  PrintArray, ADDR array, ARRAY_SIZE
22     call    WaitMsg
23     call    Crlf
24 
25     call    AskForSearchVal                             ; 输入待查找的数字
26     INVOKE  BinarySearch, ADDR array, ARRAY_SIZE, eax   ; 二叉搜索
27     call    ShowResults                                 ; 输出搜索结果
28     call    WaitMsg
29 
30     exit
31 main ENDP
32 
33 AskForSearchVal PROC
34 .data
35 prompt BYTE "Signed integer to find: ",0
36 .code
37     call    Crlf
38     mov     edx, OFFSET prompt
39     call    WriteString
40     call    ReadInt
41     ret
42 AskForSearchVal ENDP
43 
44 ShowResults PROC
45 .data
46 msg1 BYTE "Not found.",0
47 msg2 BYTE "Found at index:",0
48 .code
49 .IF eax == -1
50     mov     edx, OFFSET msg1
51     call    WriteString
52 .ELSE
53     mov     edx, OFFSET msg2
54     call    WriteString
55     call    WriteDec
56 .ENDIF
57     call    Crlf
58     ret
59 ShowResults ENDP
60 
61 END main
 1 ; FillArray.asm,用 [LowerRange, UpperRange - 1] 之间随机的整数来填充数组
 2 INCLUDE Irvine32.inc
 3 
 4 .code
 5 FillArray PROC USES eax edi ecx edx, pArray:PTR DWORD, Count:DWORD, LowerRange:SDWORD, UpperRange:SDWORD          
 6 
 7     mov     edi, pArray
 8     mov     ecx, Count
 9     mov     edx, UpperRange
10     sub     edx, LowerRange
11     cld                         ; 清除方向标志位
12 
13 L1: 
14     mov     eax, edx
15     call    RandomRange
16     add     eax, LowerRange
17     stosd                       ; eax 的值保存到 [edi]
18     loop    L1
19 
20     ret
21 FillArray ENDP
22 
23 END
 1 ; PrintArray.asm,打印数组
 2 INCLUDE Irvine32.inc
 3 
 4 .code
 5 PrintArray PROC USES eax ecx edx esi, pArray:PTR DWORD, Count:DWORD
 6 
 7 .data
 8 comma BYTE ", ",0               ; 逗号
 9 .code
10     mov     esi, pArray
11     mov     ecx, Count
12     cld
13 
14 L1:
15     lodsd                       ; 读取 [ESI] 给 eax
16     call    WriteInt       
17     mov     edx, OFFSET comma
18     call    Writestring 
19     loop    L1
20 
21     call    Crlf
22     ret
23 PrintArray ENDP
24 
25 END
 1 ; BubbleSort.asm,冒泡排序
 2 INCLUDE Irvine32.inc
 3 
 4 .code
 5 BubbleSort PROC USES eax ecx esi, pArray:PTR DWORD, Count:DWORD
 6 
 7     mov     ecx, Count
 8     dec     ecx             ; 外层循环 ecx -->0
 9 
10 L1:    
11     push    ecx             ; 内层循环,保存 ecx
12     mov     esi, pArray    
13 
14 L2:
15     mov     eax, [esi]      ; 取出相邻两个元素作比较
16     cmp     [esi + 4] ,eax
17     jge     L3              ; pArray[esi] < pArray[esi + 1] 跳转,不发生交换
18     xchg    eax, [esi+4]    
19     mov    [esi], eax
20 
21 L3:    
22     add    esi, 4           ; 后移一位
23     loop    L2         
24 
25     pop    ecx              ; 退到外层循环以前恢复 ecx
26     loop L1            
27 
28 L4:    
29     ret
30 BubbleSort ENDP
31 
32 END
 1 ; BinarySearch.asm,二分搜索
 2 INCLUDE Irvine32.inc
 3 
 4 .code
 5 BinarySearch PROC USES ebx edx esi edi, pArray:PTR DWORD, Count:DWORD, searchVal:DWORD
 6 
 7 LOCAL first:DWORD, last:DWORD, mid:DWORD
 8 
 9     mov     first, 0
10     mov     eax, Count
11     dec     eax
12     mov     last, eax
13     mov     edi, searchVal
14     mov     ebx, pArray
15 
16 L1:                         ; first <= last
17     mov     eax, first
18     cmp     eax, last
19     jg     L5               ; first > last,退出搜索
20        
21     mov     eax, last       ; 计算 mid
22     add     eax, first
23     shr     eax, 1
24     mov     mid, eax
25 
26     mov     esi, mid
27     shl     esi, 2              ; 下标乘以 4,变成数组偏移量
28     mov     edx, [ebx + esi]    ; EDX = pArray[mid]
29       
30     cmp     edx, edi        ; 比较 edx 和 查找的值
31     jge     L2              ; edx >= searchval 跳转
32     mov     eax, mid        ; first = mid + 1
33     inc     eax
34     mov     first, eax
35     jmp     L4
36 
37 L2:    
38     cmp     edx,edi         ; 比较 edx 和 查找的值  
39     jle     L3              ; edx <= searchval 跳转
40     mov     eax, mid        ; last = mid - 1
41     dec     eax
42     mov     last, eax
43     jmp     L4
44 
45 L3:    
46     mov     eax, mid        ; edx == searchval
47     jmp     L9              ; 返回,eax即为找到的下标
48 
49 L4:    
50     jmp     L1              ; 调整过 first 或 last,继续搜索
51 
52 L5:    
53     mov     eax, -1         ; 没找到
54 L9:    
55     ret
56 BinarySearch ENDP
57 
58 END

猜你喜欢

转载自www.cnblogs.com/cuancuancuanhao/p/9648847.html