汇编语言-016(SCASB 、STOSB 、LODSD 、数组中的取值、二维数组操作、冒泡排序和二分查找、CMPSW )

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
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值