汇编语言(基于x86处理器)
【美】基普·欧文(Kip Irvine)
第九章 字符串和数组
为了对内存进行高速访问,对字符串原语指令进行了优化,这些指令包括
- MOVS:传送字符串数据
- CMPS:比较字符串
- SCAS:扫描字符串
- STOS:存储字符串数据
- LODS:将字符串加载到累加器
在对字节、字或双字进行操作时,每个字符串原语指令都分别加上后缀B、W或D。
前缀REP利用变址寄存器的自动增减重复执行字符串原语指令。例如,REPNE与SCASB组合时,它就一直扫描内存字节单元,直到由EDI指向的内存数值等于AL寄存器中的值。每次执行字符串原始指令过程中,方向标志位DF决定变址寄存器是增加还是减少。
字符串和数组实际上是一样的。以往,一个字符串就是由单字节ASCII码数组构成的,但是现在字符串也可以包含16位Unicode字符。字符串与数组之间唯一的重要区别就是:字符串通常用一个空字节(包含0)表示结束。
数组操作是计算密集型的,因为一般它会涉及循环算法。大多数程序80%~90%的运行时间都用来执行其代码的一小部分。因此,通过减少循环中指令的条数和复杂度就可以提高软件的速度。由于汇编语言能控制每个细节,所以它是极好的代码优化工具。比如,通过用寄存器来代替内存变量,就能够优化代码块。或者可以使用本章介绍的字符串处理指令,而不是用MOV和CMP指令。
本章介绍了几个有用的字符串处理过程:Str_copy过程将一个字符串复制到另一个字符串。Str_length过程返回字符串的长度。Str_compare比较两个字符串。Str_trim从一个字符串尾部删除指定字符。Str_ucase将一个字符串转换为大写字母。
基址—变址操作数有助于处理二维数组(表)。可以将基址寄存器设置为表的行地址,而将变址寄存器设置为被选择行的列偏移量。32位模式中,所有32位通用寄存器都可以被用作基址和变址寄存器。基址—变址—偏移量操作数与基址—变址操作数类似,不同之处在于,前者还包含数组名:
[ebx+esi] ;基址—变址
array[ebx+esi] ;基址—变址—偏移量
本章还用汇编语言实现了冒泡排序和对半查找。冒泡排序把一个数组中的元素按照升序或降序排列。对几百个元素的数组来说,它有很好的效率,但是对元素个数更多的数组则效率很低。对半查找在顺序排列的数组中实现单个数值的高速搜索。它易于用汇编语言实现。