《汇编语言 基于x86处理器》第九章字符串与数组部分的代码
▶ 书中第九章的程序,主要讲了字符串相关的输入、输出,以及冒泡排序、二分搜索
● 代码,Irvine32 中的字符串库函数代码范例
- INCLUDE Irvine32.inc
- .data
- str1 BYTE "abcde////",
- str2 BYTE "ABCDE",
- msg0 BYTE "Upper case: ",
- msg1 BYTE "str1 == str2",
- msg2 BYTE "str1 < str2",
- msg3 BYTE "str1 > str2",
- msg4 BYTE "Length of str1: ",
- msg5 BYTE "Trimming: ",
- .code
- main PROC
- mov edx, OFFSET str1
- call WriteString
- call crlf
- call trim_string
- call upper_case
- call compare_strings
- call print_length
- call waitmsg
- exit
- main ENDP
- trim_string PROC ; 去掉结尾的指定字符
- INVOKE Str_trim, ADDR str1, '/'
- mov edx, OFFSET msg5
- call WriteString
- mov edx, OFFSET str1
- call WriteString
- call Crlf
- ret
- trim_string ENDP
- upper_case PROC ; 小写转大写
- mov edx, OFFSET msg0
- call WriteString
- INVOKE Str_ucase, ADDR str1
- mov edx, OFFSET str1
- call WriteString
- call Crlf
- ret
- upper_case ENDP
- compare_strings PROC ; 比较 str1 和 str2
- INVOKE Str_compare, ADDR str1, ADDR str2
- .IF ZERO?
- mov edx, OFFSET msg1 ; str1 = str2
- .ELSEIF CARRY?
- mov edx, OFFSET msg2 ; str1 < str2
- .ELSE
- mov edx, OFFSET msg3 ; str1 > str2
- .ENDIF
- call WriteString
- call Crlf
- ret
- compare_strings ENDP
- print_length PROC ; 获取字符串长度
- mov edx, OFFSET msg4
- call WriteString
- INVOKE Str_length, ADDR str1
- call WriteDec
- call Crlf
- ret
- print_length ENDP
- END main
■ 输出结果
- abcde////
- Trimming: abcde
- Upper case: ABCDE
- str1 == str2
- Length of str1:
● 用宏来计算矩阵某一行的元素的和
- INCLUDE Irvine32.inc
- mCalc_row_sum MACRO index, arrayOffset, rowSize, eltType
- LOCAL L1 ; 指定局部循环点
- push ebx
- push ecx
- push esi
- mov eax, index
- mov ebx, arrayOffset
- mov ecx, rowSize
- mul ecx ; eax = 选取行的行偏移
- add ebx, eax ; ebx = 选取行的首元素地址
- shr ecx, (TYPE eltType / ) ; 控制循环次数 byte=0, word=1, dword=2
- ; 因为循环内数组寻址使用 esi 完成的,ecx 要单独计算
- mov eax, ; 存放和
- mov esi, ; 列下标
- L1:
- IFIDNI <eltType>, <DWORD> ; DWORD 使用的寄存器不一样,区别对待
- mov edx, eltType PTR[ebx + esi*(TYPE eltType)]
- ELSE
- movzx edx, eltType PTR[ebx + esi*(TYPE eltType)]
- ENDIF
- add eax, edx
- inc esi
- loop L1
- pop esi
- pop ecx
- pop ebx
- ENDM
- .data
- tableB BYTE 10h, 20h, 30h, 40h, 50h
- RowSizeB = ($ - tableB) ; 数组定义断开,中间插入一个用于计算数组行宽的常量
- BYTE 60h, 70h, 80h, 90h, 0A0h
- BYTE 0B0h, 0C0h, 0D0h, 0E0h, 0F0h
- tableW WORD 10h, 20h, 30h, 40h, 50h
- RowSizeW = ($ - tableW)
- WORD 60h, 70h, 80h, 90h, 0A0h
- WORD 0B0h, 0C0h, 0D0h, 0E0h, 0F0h
- tableD DWORD 10h, 20h, 30h, 40h, 50h
- RowSizeD = ($ - tableD)
- DWORD 60h, 70h, 80h, 90h, 0A0h
- DWORD 0B0h, 0C0h, 0D0h, 0E0h, 0F0h
- index DWORD ; 指定要计算的行号
- .code
- main PROC
- mCalc_row_sum index, OFFSET tableB, RowSizeB, BYTE
- call WriteHex
- call Crlf
- mCalc_row_sum index, OFFSET tableW, RowSizeW, WORD
- call WriteHex
- call Crlf
- mCalc_row_sum index, OFFSET tableD, RowSizeD, DWORD
- call WriteHex
- call Crlf
- call WaitMsg
- exit
- main ENDP
- END main
● 64 位版本,主要区别就是函数声明,使用的寄存器
- ExitProcess PROT
- WriteHex64 PROTO
- Crlf PROTO
- mCalc_row_sum MACRO index, arrayOffset, rowSize, eltType
- LOCAL L1
- push rbx
- push rcx
- push rsi
- mov rax, index
- mov rbx, arrayOffset
- mov rcx, rowSize
- mul rcx
- add rbx, rax
- shr rcx, (TYPE eltType / )
- mov rax,
- mov rsi,
- L1:
- IFIDNI <eltType>, <DWORD>
- mov edx,eltType PTR[rbx + rsi*(TYPE eltType)]
- ELSE
- movzx edx,eltType PTR[rbx + rsi*(TYPE eltType)]
- ENDIF
- add rax, rdx
- inc rsi
- loop L1
- pop rsi
- pop rcx
- pop rbx
- ENDM
- .data
- tableB BYTE 10h, 20h, 30h, 40h, 50h
- RowSizeB = ($ - tableB)
- BYTE 60h, 70h, 80h, 90h, 0A0h
- BYTE 0B0h, 0C0h, 0D0h, 0E0h, 0F0h
- tableW WORD 10h, 20h, 30h, 40h, 50h
- RowSizeW = ($ - tableW)
- WORD 60h, 70h, 80h, 90h, 0A0h
- WORD 0B0h, 0C0h, 0D0h, 0E0h, 0F0h
- tableD DWORD 10h, 20h, 30h, 40h, 50h
- RowSizeD = ($ - tableD)
- DWORD 60h, 70h, 80h, 90h, 0A0h
- DWORD 0B0h, 0C0h, 0D0h, 0E0h, 0F0h
- index QWORD
- .code
- main PROC
- mCalc_row_sum index, OFFSET tableB, RowSizeB, BYTE
- call WriteHex64
- call Crlf
- mCalc_row_sum index, OFFSET tableW, RowSizeW, WORD
- call WriteHex64
- call Crlf
- mCalc_row_sum index, OFFSET tableD, RowSizeD, DWORD
- call WriteHex64
- call Crlf
- mov ecx,
- call ExitProcess
- main ENDP
- END
● 代码,冒泡排序,二分搜索
- ; BinarySearchTest.asm,测试函数
- INCLUDE Irvine32.inc
- INCLUDE BinarySearch.inc
- LOWVAL = -
- HIGHVAL = +
- ARRAY_SIZE =
- .data
- array DWORD ARRAY_SIZE DUP(?)
- .code
- main PROC
- call Randomize ; 初始化随机数种子
- INVOKE FillArray, ADDR array, ARRAY_SIZE, LOWVAL, HIGHVAL ; 用随机数填充数组
- INVOKE PrintArray, ADDR array, ARRAY_SIZE ; 显示数组内容
- call WaitMsg
- call Crlf
- INVOKE BubbleSort, ADDR array, ARRAY_SIZE ; 冒泡排序
- INVOKE PrintArray, ADDR array, ARRAY_SIZE
- call WaitMsg
- call Crlf
- call AskForSearchVal ; 输入待查找的数字
- INVOKE BinarySearch, ADDR array, ARRAY_SIZE, eax ; 二叉搜索
- call ShowResults ; 输出搜索结果
- call WaitMsg
- exit
- main ENDP
- AskForSearchVal PROC
- .data
- prompt BYTE "Signed integer to find: ",
- .code
- call Crlf
- mov edx, OFFSET prompt
- call WriteString
- call ReadInt
- ret
- AskForSearchVal ENDP
- ShowResults PROC
- .data
- msg1 BYTE "Not found.",
- msg2 BYTE "Found at index:",
- .code
- .IF eax == -
- mov edx, OFFSET msg1
- call WriteString
- .ELSE
- mov edx, OFFSET msg2
- call WriteString
- call WriteDec
- .ENDIF
- call Crlf
- ret
- ShowResults ENDP
- END main
- ; FillArray.asm,用 [LowerRange, UpperRange - 1] 之间随机的整数来填充数组
- INCLUDE Irvine32.inc
- .code
- FillArray PROC USES eax edi ecx edx, pArray:PTR DWORD, Count:DWORD, LowerRange:SDWORD, UpperRange:SDWORD
- mov edi, pArray
- mov ecx, Count
- mov edx, UpperRange
- sub edx, LowerRange
- cld ; 清除方向标志位
- L1:
- mov eax, edx
- call RandomRange
- add eax, LowerRange
- stosd ; eax 的值保存到 [edi]
- loop L1
- ret
- FillArray ENDP
- END
- ; PrintArray.asm,打印数组
- INCLUDE Irvine32.inc
- .code
- PrintArray PROC USES eax ecx edx esi, pArray:PTR DWORD, Count:DWORD
- .data
- comma BYTE ", ", ; 逗号
- .code
- mov esi, pArray
- mov ecx, Count
- cld
- L1:
- lodsd ; 读取 [ESI] 给 eax
- call WriteInt
- mov edx, OFFSET comma
- call Writestring
- loop L1
- call Crlf
- ret
- PrintArray ENDP
- END
- ; BubbleSort.asm,冒泡排序
- INCLUDE Irvine32.inc
- .code
- BubbleSort PROC USES eax ecx esi, pArray:PTR DWORD, Count:DWORD
- mov ecx, Count
- dec ecx ; 外层循环 ecx -->0
- L1:
- push ecx ; 内层循环,保存 ecx
- mov esi, pArray
- L2:
- mov eax, [esi] ; 取出相邻两个元素作比较
- cmp [esi + ] ,eax
- jge L3 ; pArray[esi] < pArray[esi + 1] 跳转,不发生交换
- xchg eax, [esi+]
- mov [esi], eax
- L3:
- add esi, ; 后移一位
- loop L2
- pop ecx ; 退到外层循环以前恢复 ecx
- loop L1
- L4:
- ret
- BubbleSort ENDP
- END
- ; BinarySearch.asm,二分搜索
- INCLUDE Irvine32.inc
- .code
- BinarySearch PROC USES ebx edx esi edi, pArray:PTR DWORD, Count:DWORD, searchVal:DWORD
- LOCAL first:DWORD, last:DWORD, mid:DWORD
- mov first,
- mov eax, Count
- dec eax
- mov last, eax
- mov edi, searchVal
- mov ebx, pArray
- L1: ; first <= last
- mov eax, first
- cmp eax, last
- jg L5 ; first > last,退出搜索
- mov eax, last ; 计算 mid
- add eax, first
- shr eax,
- mov mid, eax
- mov esi, mid
- shl esi, ; 下标乘以 4,变成数组偏移量
- mov edx, [ebx + esi] ; EDX = pArray[mid]
- cmp edx, edi ; 比较 edx 和 查找的值
- jge L2 ; edx >= searchval 跳转
- mov eax, mid ; first = mid + 1
- inc eax
- mov first, eax
- jmp L4
- L2:
- cmp edx,edi ; 比较 edx 和 查找的值
- jle L3 ; edx <= searchval 跳转
- mov eax, mid ; last = mid - 1
- dec eax
- mov last, eax
- jmp L4
- L3:
- mov eax, mid ; edx == searchval
- jmp L9 ; 返回,eax即为找到的下标
- L4:
- jmp L1 ; 调整过 first 或 last,继续搜索
- L5:
- mov eax, - ; 没找到
- L9:
- ret
- BinarySearch ENDP
- END
《汇编语言 基于x86处理器》第九章字符串与数组部分的代码的更多相关文章
- 《汇编语言 基于x86处理器》第八章高级过程部分的代码 - 两种规范计算数组元素的和
▶ 输入 Count 个 32 位有符号整数,计算他们的和 ● 代码,使用堆栈传参 ;// Sum_main.asm,主过程 INCLUDE Irvine32.inc EXTERN PromptFor ...
- 《汇编语言 基于x86处理器》第十一章 MS-DOS 编程部分的代码 part 2
▶ 书中第十一章的程序,主要讲了 Windows 接口,在小黑框中进行程序交互 ● 在屏幕指定位置输出带自定义属性的文字 INCLUDE Irvine32.inc .data outHandle HA ...
- 《汇编语言 基于x86处理器》第十三章高级语言接口部分的代码 part 2
▶ 书中第十三章的程序,主要讲了汇编语言和 C/++ 相互调用的方法 ● 代码,汇编中调用 C++ 函数 ; subr.asm INCLUDE Irvine32.inc askForInteger P ...
- 《汇编语言 基于x86处理器》前五章的小程序
▶ 书中前五章的几个小程序,基本的运算操作,使用了作者的库 Irvine32 和 Irvine64(一开始以为作者网站过期了,各网站上找到的文件大小都不一样,最后发现是要搭梯子 Orz,顺利下载).注 ...
- 《汇编语言 基于x86处理器》第十二章浮点数部分的代码
▶ 书中第十二章的程序,主要讲了 FPU 的指令和浮点数计算的过程 ● 代码,简单的 32 为浮点数测试 INCLUDE Irvine32.inc INCLUDE macros.inc .data f ...
- 《汇编语言 基于x86处理器》第七章整数运算部分的代码
▶ 书中第七章的程序,使用各种位移运算,加深了对内存.寄存器中整数类型变量存储的认识 ● 代码,双字数组右移 4 位 INCLUDE Irvine32.inc COUNT = ; 右移位数 .data ...
- 《汇编语言 基于x86处理器》第六章条件处理部分的代码
▶ 书中第六章的程序,使用了条件判断和跳转来实现一些功能 ● 代码,查找数组首个非零值 INCLUDE Irvine32.inc .data intArray SWORD , , , , , , , ...
- 《汇编语言 基于x86处理器》第十章 - 运行一个 16位实地址汇编程序
▶ 书上第 10 章,主要讲了宏,引用了一个 16 位实地址的程序,从代码开始到运行 ● 代码 ; main.asm INCLUDE Macros.inc IF IsDefined( RealMode ...
- 《汇编语言 基于x86处理器》第十章结构和宏部分的代码
▶ 书中第十章的程序,主要讲了结构与宏的使用 ● 代码,使用结构,对比是否对齐的性能差距 INCLUDE Irvine32.inc INCLUDE macros.inc structN STRUCT ...
随机推荐
- 源代码安装Apache、Mysql、PHP
源代码软件的优点: 获得最新版,能及时修复bug: 能自行修改和定制: 源代码打包形式: .tar.gz和.tar.bz2格式居多: 完整性校验: md5sum校验工具 ...
- 黄聪:C#如何使用fiddlercoreCapture监控手机APP
1.去下载Fiddler:https://www.telerik.com/download/fiddler 2.安装Fiddler,按下图所示导出证书,导出后在桌面得到:FiddlerRoot.cer ...
- PHP 数据运算类型都有哪些?
四种标量类型:布尔型 boolean $bo=TRUE; $bo=FALSE;整型 integer $bo=1; $bo=-12;浮点型 float/double $bo=1.001; $bo=3 ...
- 胖子哥的大数据之路(9)-数据仓库金融行业数据逻辑模型FS-LDM
引言: 大数据不是海市蜃楼,万丈高楼平地起只是意淫,大数据发展还要从点滴做起,基于大数据构建国家级.行业级数据中心的项目会越来越多,大数据只是技术,而非解决方案,同样面临数据组织模式,数据逻辑模式的问 ...
- C++进阶--Named Parameter Idiom
//############################################################################ /* Named Parameter Id ...
- python-selenium并发执行测试用例(方法一 各模块每一条并发执行)
总执行代码: # coding=utf-8import unittest,os,timeimport HTMLTestRunnerimport threadingimport syssys.path. ...
- html代码段
添加icon<link rel="shortcut icon" href="img/100du.ico"/>
- OpenJuege 兔子与星空
总时间限制: 1000ms 内存限制: 10000kB 描述 很久很久以前,森林里住着一群兔子.兔子们无聊的时候就喜欢研究星座.如图所示,天空中已经有了n颗星星,其中有些星星有边相连.兔子们希望删 ...
- Delphi2010/XE2下隐藏程序系统任务栏的图标
Delphi7代码: SetWindowLong(Application.Handle,GWL_EXSTYLE,WS_EX_TOOLWINDOW); 以上的代码在Delphi7中可以用,但是在Delp ...
- IIS 修改并发连接数
http://www.cnblogs.com/dudumao/p/4078687.html