1: SCASB : (字节)将AL的值与EDI寻址的一个字比较。进行在一个字符串检索特定的字符
.386
.model flat,stdcall
.stack 4096
ExitProcess PROTO,dwExitCode:DWORD
.data
alpha BYTE "ABCDEFGH",0
.code
main PROC
mov edi,OFFSET alpha ;EDI指向字符串
mov al,'F' ;检索字符F
mov ecx,LENGTHOF alpha ;设置检索计数器
cld ;方向为正向
repne scasb ;不相等则重复
jnz quit ;若未发现字符则退出
dec edi ;发现字符,EDI减1,因为执行scasb后,edi增加1了
quit:
INVOKE ExitProcess,0
main ENDP
END main
2:STOSB : (字节)将AL的值复制到EDI寻址的位置上,可以加上rep重复操作
.386
.model flat,stdcall
.stack 4096
ExitProcess PROTO,dwExitCode:DWORD
.data
Count =100
string1 BYTE Count DUP(?)
.code
main PROC
mov al,0FFh ;要保存的数值
mov edi,OFFSET string1 ;EDI指向目标字符串
mov ecx,Count
cld
rep stosb ;用AL的内容实现填充
INVOKE ExitProcess,0
main ENDP
END main
3:LODSD : (双字)交一个双字数组中的每个元素都乘以同一个常数
.386
.model flat,stdcall
.stack 4096
ExitProcess PROTO,dwExitCode:DWORD
.data
array DWORD 1,2,3,4,5,6,7,8,9,10
multiplier DWORD 10
;将一个32位整数数组中的每个元素都乘以一个常数
.code
main PROC
cld
mov esi,OFFSET array ;源数组索引
mov edi,esi ;目标数组索引
mov ecx,LENGTHOF array ;循环计数器
L1:
lodsd ;将[ESI]加载到EAX
mul multiplier ;与常数相乘
stosd ;将EAX保存到[EDI]
loop L1
INVOKE ExitProcess,0
main ENDP
END main
4:数组中的取值,基址——变址操作数,将两个寄存器(称为基址和变址)相加,生成一个偏移地址
.386
.model flat,stdcall
.stack 4096
ExitProcess PROTO,dwExitCode:DWORD
.data
array WORD 1000h,2000h,3000h
.code
main PROC
mov ebx,OFFSET array
mov esi,2
mov ax,[ebx+esi] ;AX=2000h
mov edi,OFFSET array
mov ecx,4
mov ax,[edi+ecx] ;AX = 3000h
mov ebp,OFFSET array
mov esi,0
mov ax,[ebp+esi]
INVOKE ExitProcess,0
main ENDP
END main
5:二维数组中取值
.386
.model flat,stdcall
.stack 4096
ExitProcess PROTO,dwExitCode:DWORD
.data
tableB BYTE 10h,20h,30h,40h,50h
RowSize = ($ - tableB)
BYTE 60h,70h,80h,90h,0A0h
BYTE 0B0h,0C0h,0D0h,0E0h,0F0h
.code
main PROC
row_index = 1
column_index = 2
mov ebx,OFFSET tableB ;表的偏移量
add ebx,RowSize * row_index ;行的偏移量
mov esi,column_index
mov al,[ebx+esi] ;AL = 80h
INVOKE ExitProcess,0
main ENDP
END main
6:计算二维数组中某一行的之和
.386
.model flat,stdcall
.stack 4096
ExitProcess PROTO,dwExitCode:DWORD
.data
tableB BYTE 10h,20h,30h,40h,50h
RowSize = ($ - tableB)
BYTE 60h,70h,80h,90h,0A0h
BYTE 0B0h,0C0h,0D0h,0E0h,0F0h
.code
main PROC
row_index = 1
column_index = 2
mov ebx,OFFSET tableB ;表的偏移量
add ebx,RowSize * row_index ;行的偏移量
mov esi,column_index
mov al,[ebx+esi] ;AL = 80h
INVOKE ExitProcess,0
main ENDP
;计算字节矩阵中一行的和数
;接收:EBX=表偏移量,EAX=行索引
;ECX=按字节计的行大小
;返回:EAX为和数
calc_row_sum PROC USES ebx ecx edx esi
mul ecx ;行索引 * 行大小
add ebx,eax ;行偏移量
mov eax,0 ;累加器
mov esi,0 ;列索引
L1:
movzx edx,BYTE PTR[ebx + esi] ;取一个字节
add eax,edx ;与累加器相加
inc esi ;行中下一个字节
loop L1
ret
calc_row_sum ENDP
END main
7:二维数组中使用比例因子寻址取值
.386
.model flat,stdcall
.stack 4096
ExitProcess PROTO,dwExitCode:DWORD
.data
tableW WORD 10h,20h,30h,40h,50h
RowSizeW = ($ - tableW)
WORD 60h,70h,80h,90h,0A0h
WORD 0B0h,0C0h,0D0h,0E0h,0F0h
.code
main PROC
row_index = 1
column_index = 2
mov ebx,OFFSET tableW ;表偏移量
add ebx,RowSizeW * row_index ;行偏移量
mov esi,column_index
mov ax,[ebx + esi*TYPE tableW] ;AX = 0080h
INVOKE ExitProcess,0
main ENDP
END main
8:基址——变址——偏移量操作数,用一个偏移量、一个基址寄存器、一个变址寄存器和一个可选的比例因子生成有效地址
.386
.model flat,stdcall
.stack 4096
ExitProcess PROTO,dwExitCode:DWORD
.data
tableD DWORD 10h,20h,30h,40h,50h
RowSizeD = ($ - tableD)
DWORD 60h,70h,80h,90h,0A0h
DWORD 0B0h,0C0h,0D0h,0E0h,0F0h
.code
main PROC
row_index = 1
column_index = 2
mov ebx,RowSizeD * row_index ;行索引
mov esi,column_index ;列索引
mov eax,tableD[ebx + esi*TYPE tableD] ;AX = 00000080h
INVOKE ExitProcess,0
main ENDP
END main
9:64位基址——变址——偏移量操作数做法
BinarySearch.asm
include BinarySearch.inc
.code
BinarySearch PROC USES ebx edx esi edi,
pArray:PTR DWORD, ;数组指针
Count:DWORD, ;数组大小
searchVal:DWORD ;给定查找数值
LOCAL first:DWORD,;first的位置
last:DWORD, ;last的位置
mid:DWORD ;中点
mov first,0 ;first = 0
mov eax,Count ;last = (Count - 1)
dec eax
mov last,eax
mov edi,searchVal ;EDI = searchVal
mov ebx,pArray ;EBX 为 数组指针
L1:
;当first<=last时
mov eax,first
cmp eax,last
jg L5 ;退出查找
;mid = (last+first)/2
mov eax,last
add eax,first
shr eax,1
mov mid,eax
;EDX = values[mid]
mov esi,mid
shl esi,2 ;将mid 值乘4
mov edx,[ebx+esi] ;EDX = values[mid]
;若EDX < searchVal(EDI)
cmp edx,edi
jge L2
;first = mid +1
mov eax,mid
inc eax
mov first,eax
jmp L4
;否则,若EDX>searchVal(EDI)
L2:
cmp edx,edi
jle L3 ;可选项
;last=mid - 1
mov eax,mid
dec eax
mov last,eax
jmp L4
;否则返回mid
L3:
mov eax,mid ;发现数值
jmp L9 ;返回mid
L4:
jmp L1 ;继续循环
L5:
mov eax,-1 ;查找失败
L9:
ret
BinarySearch ENDP
END
BinarySearch.inc
.386
.model flat,stdcall
.stack 4096
;冒泡排序/对半查找程序中使用的过程原型
;在32位有符号整数数组中查找一个数
BinarySearch PROTO,
pArray:PTR DWORD, ;指向数组
Count:DWORD, ;数组大小
searchVal:DWORD ;查找数值
;用32位有符号随机整数填充数组
FillArray PROTO,
pArray:PTR DWORD, ;指向数组
Count:DWORD, ;元素个数
LowerRange:SDWORD, ;随机数的下限
UpperRange:SDWORD ;随机数的上限
;将32位有符号整数数组定到标准输出
PrintArray PROTO,
pArray:PTR DWORD,
Count:DWORD,
;将数组按升序排列
BubbleSort PROTO,
pArray:PTR DWORD,
Count:DWORD
BinarySearchTest.asm
include Irvine32.inc
include BinarySearch.inc
LOWVAL = -5000 ;最小值
HIGHVAL = +5000 ;最大值
ARRAY_SIZE = 50 ;数组大小
.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
;执行冒泡排序并再次显示数组
INVOKE BubbleSort ,ADDR array,ARRAY_SIZE
INVOKE PrintArray,ADDR array,ARRAY_SIZE
;实现对半查找
call AskForSearchVal ;用EAX返回
INVOKE BinarySearch,
ADDR array,ARRAY_SIZE,eax
call ShowResults
exit
main ENDP
;请求用户输入一个有符号整数
;接收:无
;返回:EAX = 用户输入的数值
AskForSearchVal PROC
.data
prompt BYTE "Enter a signed decimal integer "
BYTE "in the range of -5000 to +5000 "
BYTE "to find in the array: ",0
.code
call Crlf
mov edx,OFFSET prompt
call WriteString
call ReadInt
ret
AskForSearchVal ENDP
;显示对半查找的结果值
;接收:EAX = 被显示数的位置
;返回:无
ShowResults PROC
.data
msg1 BYTE "The value was not found,",0
msg2 BYTE "The value was found at position ",0
.code
.IF eax == -1
mov edx,OFFSET msg1
call WriteString
.ELSE
mov edx,OFFSET msg2
call WriteString
call WriteDec
.ENDIF
call Crlf
call Crlf
ret
ShowResults ENDP
END main
BubbleSort.asm
include BinarySearch.inc
.code
;使用冒泡算法,将一个32位有符号整数数组升序进行排列
;接收:数组指针,数组大小
;返回:无
BubbleSort PROC USES eax ecx esi,
pArray:PTR DWORD, ;数组指针
Count:DWORD ;数组大小
mov ecx,Count
dec ecx ;计数值减1
L1:
push ecx ;保存外循环计数值
mov esi,pArray; 指向第一个数值
L2:
mov eax,[esi] ;取数组元素值
cmp [esi+4],eax ;比较两个数值
jg L3 ;如果[ESI]<=[ESI+4],不交换
xchg eax,[esi+4];交换两数
mov [esi],eax
L3:
add esi,4 ;两个指针都向前移动一个元素
loop L2 ;内循环
pop ecx ;恢复外循环计数值
loop L1 ;若计数值不等于0,则继续外循环
L4:
ret
BubbleSort ENDP
END
FillArray.asm
include Irvine32.inc
.code
;用LowerRange到(UpperRange-1之间的32位随机有符号整数序列填充数组)
;返回:无
FillArray PROC USES eax edi ecx edx,
pArray:PTR DWORD, ;数组指针
Count:DWORD, ;元素个数
LowerRange:SDWORD, ;范围下限
UpperRange:SDWORD ;范围上限
mov edi,pArray ;EDI为数组指针
mov ecx,Count ;循环计数器
mov edx,UpperRange
sub edx,LowerRange ;EDX = 绝对范围0..n
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
;将32位有符号十进制整数数组写到标准输出,数值用逗号隔开
;接收:数组指针,数组大小
;返回:无
PrintArray PROC USES eax ecx edx esi,
pArray:PTR DWORD,
Count:DWORD
.data
comma BYTE ", ",0
.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
10:CMPSW : 比较两个16位数组,找出第一个相同的值
.386
.model flat,stdcall
.stack 4096
ExitProcess PROTO,dwEixtCode:DWORD
.data
sourceW WORD 1,2,3,4,5
targetW WORD 5,4,3,2,1
.code
main PROC
mov esi,OFFSET sourceW
mov edi,OFFSET targetW
cld
mov ecx,LENGTHOF sourceW
repne cmpsw
sub esi,TYPE WORD
mov ax,[esi]
INVOKE ExitProcess,0
main ENDP
END main