汇编语言-006(数组操作 、字符串应用、PUSHFD_POPFD 、PUSHAD_POPAD 、 子程序 函数、 USES 、 INC_DEC )

1:
计算斐波那契数列前7个数值之和

.386
.model flat,stdcall

.stack 4096
ExitProcess PROTO,dwExitCode:DWORD

.data

.code
main PROC
    mov esi,1
	mov edi,1
	mov eax,2
	mov ecx,5
L1: 
	mov ebx,esi
	add ebx,edi
	mov esi,edi
	mov edi,ebx
	add eax,ebx
	loop L1
	INVOKE ExitProcess,0
main ENDP
END main

2:
数组反向,使用TYPE,LENGTHOF运行符和 TEXTEQU伪指令来应对往后程序的数值大小和类型可能变化的情况

.386
.model flat,stdcall

.stack 4096
ExitProcess PROTO,dwExitCode:DWORD

tempReg TEXTEQU <eax>
.data
List DWORD 1,2,3,4,5

.code
main PROC
    mov ecx,LENGTHOF List /2
	mov esi,0
	mov edi,LENGTHOF List - 1
L1:
	mov tempReg,List[esi * TYPE List]
	xchg tempReg,List[edi * TYPE List]
	mov List[esi * TYPE List],tempReg
	inc esi
	dec edi
	loop L1
	INVOKE ExitProcess,0
main ENDP
END main

3:
将字符串复制相反顺序到另一个字符串

.386
.model flat,stdcall

.stack 4096
ExitProcess PROTO,dwExitCode:DWORD

.data
source BYTE "This is the source string",0
target BYTE SIZEOF source DUP('#')

.code
main PROC
   mov target[SIZEOF target -1],0
   mov esi,SIZEOF target - 2
   mov edi,0
   mov ecx,SIZEOF target - 1
L1:   
   mov al,source[esi]
   mov target[edi],al
   dec esi
   inc edi
   loop L1
   INVOKE ExitProcess,0
main ENDP
END main

4:
数组元素移位,数组[10,20,30,40]移位后为[40,10,20,30]

.386
.model flat,stdcall

.stack 4096
ExitProcess PROTO,dwExitCode:DWORD

.data 
dwordList DWORD 10,20,30,40

.code
main PROC
   mov esi,LENGTHOF dwordList - 1
   mov ecx,esi
   mov ebx,dwordList[esi * TYPE dwordList]
   dec esi
L1:
   mov edi,dwordList[esi * TYPE dwordList]
   inc esi
   mov dwordList[esi * TYPE dwordList],edi
   sub esi,2
   loop L1
   mov dwordList,ebx
   INVOKE ExitProcess,0
main ENDP
END main

5:
PUSHFD_POPFD : 将标识寄存器入栈出栈

.386
.model flat,stdcall

.stack 4096
ExitProcess PROTO,dwExitCode:DWORD

.data
saveFlags DWORD ?

.code
main PROC
    pushfd          ;标识寄存器内容入栈
	pop saveFlags   ;复制给一个变量
	push saveFlags  ;被保存的标识入栈
	popfd           ;复制给标识寄存器
    INVOKE ExitProcess,0
main ENDP
END main
    

6:
PUSHAD_POPAD : 将通用寄存器入栈和反顺序出栈,顺序:eax,ecx,edx,ebx,esp,ebp,esi,edi

.386
.model flat,stdcall

.stack 4096
ExitProcess PROTO,dwExitCode:DWORD

.code
main PROC
    pushad   ;保存通用寄存器的内容 eax,ecx,edx,ebx,esp,ebp,esi,edi顺序

	;mov eax,0 ;如果有返回值在eax中后面就要注意用popad了

	popad ;反顺序出栈
	INVOKE ExitProcess,0
main ENDP
END main

7:
运用栈将字符串反转

.386
.model flat,stdcall
.stack 4096
ExitProcess PROTO,dwExitCode:DWORD

.data
aName BYTE "Abraham Lincoln",0
nameSize = ($ - aName) - 1

.code
main PROC
     ;将名字压入栈
	 mov ecx,nameSize
	 mov esi,0
L1:
    movzx eax,aName[esi] ;获取字符
	push eax              ;压入栈
	inc esi
	loop L1
	;将名字按逆序弹出栈
	;并存入aName数组
	mov ecx,nameSize
	mov esi,0
L2:
    pop eax          ;获取字符
	mov aName[esi],al;存入字符串
	inc esi
	loop L2

	INVOKE ExitProcess,0
main ENDP
END main

8:
创建过程(子程序,函数)进行数组求和

.386
.model flat,stdcall

.stack 4096
ExitProcess PROTO,dwEixtCode:DWORD

.data
array DWORD 10000h,20000h,30000h,40000h,50000h
theSum DWORD ?

.code
main PROC
    mov esi,OFFSET array    ;esi指向数组
	mov ecx,LENGTHOF array  ;数组计数器
	call ArraySum           ;计算和数
	mov theSum,eax          ;取返回的和数

	INVOKE ExitProcess,0
main ENDP

;ArraySum
;计算32位整数数组之和
;接收:ESI = 数组偏移量
;      ECX = 数组元素的个数
;返回  EAX = 数组元素之和

ArraySum PROC
       push esi
	   push ecx   ;保存esi和ecx
	   mov eax,0 
L1:
       add eax,[esi] ;将每个整数与和数相加
	   add esi,TYPE DWORD ;指向下一个整数
	   loop L1          ;按照数组大小重复
	   pop ecx      ;恢复ecx和esi
	   pop esi
	   ret     ;返回调用片
ArraySum ENDP
END main


9:
USES : USES伪指令告诉汇编器,在过程开始时生成PUSH寄存器指令,在结束时生成POP寄存器指令(可以查看反汇编窗口)

.386
.model flat,stdcall

.stack 4096
ExitProcess PROTO,dwEixtCode:DWORD

.data
array DWORD 10000h,20000h,30000h,40000h,50000h
theSum DWORD ?

.code
main PROC
    mov esi,OFFSET array    ;esi指向数组
	mov ecx,LENGTHOF array  ;数组计数器
	call ArraySum           ;计算和数
	mov theSum,eax          ;取返回的和数

	INVOKE ExitProcess,0
main ENDP

;ArraySum
;计算32位整数数组之和
;接收:ESI = 数组偏移量
;      ECX = 数组元素的个数
;返回  EAX = 数组元素之和

ArraySum PROC USES esi ecx
      
	  ;汇编器会生成将这两个寄存器入栈的指令
      ; push esi
	  ; push ecx   ;保存esi和ecx

	   mov eax,0 
L1:
       add eax,[esi] ;将每个整数与和数相加
	   add esi,TYPE DWORD ;指向下一个整数
	   loop L1          ;按照数组大小重复

	   ;汇编器会生成将这两个寄存器出栈的指令
	  ;pop ecx      ;恢复ecx和esi
	  ;pop esi
	   ret     ;返回调用片
ArraySum ENDP
END main

10:
INC_DEC : INC 伪指令自增,DEC伪指令自减

.386
.model flat,stdcall

.stack 4096
ExitProcess PROTO,dwExitCode:DWORD

.data
myWord WORD 1000h

.code
main PROC
    inc myWord
	mov bx,myWord
	dec bx
	INVOKE ExitProcess,0
main ENDP
END main
上一篇:golang int64 json.Unmarshal精度丢失问题


下一篇:使用firewall-cmd限制ssh只能从指定IP段访问