查看: 61|回复: 0

汇编语言2

[复制链接]

5

主题

0

回帖

0

积分

热心网友

金币
0
阅读权限
220
精华
0
威望
0
贡献
0
在线时间
0 小时
注册时间
2009-9-7
发表于 2020-11-22 01:14:00 | 显示全部楼层 |阅读模式

汇编语言学习002

使用汇编语言实现简单的字符数组反向输出,以及字符数组的打印

.586
.MODEL flat,stdcall
option casemap:none

include windows.inc
include kernel32.inc
include user32.inc
include msvcrt.inc

includelib kernel32.lib
includelib user32.lib
includelib msvcrt.lib

;目标1,创建一个reverse函数,参数是一个字符串,返回byte数组
;目标2,创建一个打印数组的函数
.data
string1 byte "This is a great test!",0;以空字符结尾,
next dword 0ah
reverse byte sizeof string1 dup(0);将数组初始化为0
sourcesize byte sizeof string1
Iter1 dword 0
Iter2 byte '1','2','3','4','a','j'

.code
reverseFun proc
	movzx ecx,sourcesize
	dec ecx
	xor esi,esi
l1:
	movzx eax,string1[esi];不能把esp置为0,esp内存储栈指针
	push eax
	inc esi
	loop l1 ;第一次循环,每一个字符都入栈
	xor esi,esi
	mov ecx,sizeof string1;确定l2的循环次数
	sub ecx,1  ;因为下面弹出了空字符,导致字符数组长度减一
;	pop eax;弹出空字符,这样reverse数组中的字符串不会是以空字符开头
l2:
	pop eax
	mov reverse[esi],al
	inc esi
	loop l2 ;第二次循环,每一个字符依序存放在reverse数组中
	ret
reverseFun ENDP
print1 proc
;	mov esi,0
;	mov ecx,sizeof string1
;	movzx eax,reverse[esi];二者大小不同,需要自动扩展
	;mov Iter2,al
	;push offset Iter2
;	push eax
	push offset reverse
	call crt_printf;以空字符开头的字符串不能被打印出
	add esp,4
	ret
print1 ENDP
main proc
	;先完成方法一
	call reverseFun
	;完成方法三,打印出倒置数组
	call print1
	push offset next     ;换行,要注意的是,它不能直接压0ah
	call crt_printf      ;
	add esp,4			 ;
	push offset string1
	call crt_printf
	add esp,4
	push offset next    ;换行
	call crt_printf     ;
	add esp,4           ;
	push offset reverse
	call crt_printf  
	add esp,4 
	push offset next    ;换行
	call crt_printf     ;
	add esp,4           ;

	mov ecx,offset lengthof Iter2
	mov esi,ecx   ;保存ecx,因为每次ecx在函数调用后都会改变,因此需要恢复
	xor ebx,ebx
l4:
	movzx eax,[Iter2+ebx];eax中存放的是Iter2中的对应位置的值
	inc ebx
	mov Iter1,eax ;将eax的值放进Iter1中
	push offset Iter1 ;将Iter2中的值,一个一个拿出来打印
;	push eax;这样的运行时call会报错,这样就是直接将eax里面的值当做地址
	call crt_printf
	add esp,4
	push offset next    ;换行
	call crt_printf     ;
	add esp,4           ;
	mov ecx,esi   ;恢复ecx,因为每次循环后都会导致ecx自动减一,所以不能先将esi的值减一
	sub esi,1	  ;将esi的值减一,这意味着下一次ecx恢复时,能够是正确的值
	loop l4   
	push 0
	call ExitProcess
main ENDP
END main

运行结果:

!tset taerg a si sihT
This is a great test!
!tset taerg a si sihT
1
2
3
4
a
j

一些笔记

计算数组长度
.data
numArray dword 0,1,2,3,4,5
.code
main proc
	mov eax,offset lengthof numArray
	
取出数组中的值(一次循环)
	movzx eax,[Iter2+ebx];eax中存放的是Iter2中的对应位置的值
	inc ebx
	mov Iter1,eax ;将eax的值放进Iter1中
	push offset Iter1 ;将Iter2中的值,一个一个拿出来打印
;	push eax;这样的运行时call会报错,这样就是直接将eax里面的值当做地址
	call crt_printf
	add esp,4
	push offset next    ;换行
	call crt_printf     ;
	add esp,4           ;
	mov ecx,esi   ;恢复ecx,因为每次循环后都会导致ecx自动减一,所以不能先将esi的值减一
	sub esi,1	

今天主要学习了函数的调用以及类型的声明,简单了解了循环的实现。



来源:https://www.cnblogs.com/youxunle/p/14018106.html
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

相关侵权、举报、投诉及建议等,请发 E-mail:qiongdian@foxmail.com

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.

在本版发帖返回顶部