《汇编语言 基于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 ...
随机推荐
- msp430学习笔记-USART
本文引用:http://bbs.ednchina.com/BLOG_ARTICLE_3013784.HTM MSP430F149有两个USART通讯端口,其性能完全一样,每个通讯口可通过RS232和R ...
- 修改machine.config遇到System.Net.ServicePointManager 的类型初始值设定项引发异常
<system.net>节点应该在</configuration>上面添加,即config页尾. 而不是在<configuration> 后面添加. 在</s ...
- Python Selenium set Chrome Preference Download Location.
def set_chrome_pref(self): chromeOptions = webdriver.ChromeOptions() prefs = {"download.default ...
- 【Mysql+shell】查询结果导出到文件,文件数据导入到数据库
Shell: 执行Mysql查询,并将查询结果导出到文件 直接使用Mysql执行查询 mysql> use xxx_dbName; mysql> select * from log_06 ...
- PAT 甲级 1006 Sign In and Sign Out (25)(25 分)
1006 Sign In and Sign Out (25)(25 分) At the beginning of every day, the first person who signs in th ...
- Oracle 存储过程起步
存储过程的注释不能写在第一行 select后面要有into create or replace procedure DelEmp(v_empno in emp.empno%type) AS No_re ...
- docker镜像创建redis5.0.3容器集群
拉取redis5.0.3镜像 # docker pull daocloud.io/library/redis:5.0.3 [root@localhost ~]# docker pull daoclou ...
- Linux 下 MQ 的安装
在WebSphere MQ 7.1版本以前,同时只能有一个产品的安装实例,在UNIX和Linux系统上,/usr/lib,/usr/bin和/usr/include目录下会增加一些软连接,也指向了这个 ...
- GDAL 地图切片层级计算公式
作者: 蔡建良 2016-7-6 地图瓦片起始层数: xMin=栅格数据最小经度 xMax=栅格数据最大经度 起始层数=Log(第0层经纬度跨度/当前地图的经纬度跨度,2) minzoom = (in ...
- Linux入门:常用命令:查看硬盘、分区、CPU、内存信息
查看硬盘信息 $df -lh #查看所有硬盘的使用状 $du -sh /etc #查看etc目录大小 #获得文件大小很方便,主要是目录 外部系统挂载 $mount ...