汇编 w5-1

本文深入探讨了汇编语言中子程序间参数传递的方法,特别是通过堆栈传递数组长度和偏移地址的过程。介绍了输入、判断及输出子程序的设计,并强调了平衡堆栈的重要性。
;代码转换
include irvine32.inc
.data	
dat	word 10 dup(?)	;对于这个参数设计模式不太明白
p	word 10 dup(?)
no	word ?
.code	
main	proc
	call input

	push lengthof dat
	push offset dat
	call judge
	call output
	exit

main	endp

input	proc		;子程序:输入数组
	push esi
	push ecx
	push ebx
	push eax
	mov ebx,offset dat
	mov ecx,10
	xor esi,esi

start:	cmp ecx,0
	jz done1
	xor eax,eax
	call readint	;这种输出模式每输入一个数都要换行
	mov dat[esi*2],ax
	inc esi
	dec ecx
	jmp start
	
done1:	pop eax
	pop ebx
	pop ecx
	pop esi
	ret
input	endp

judge	proc		;子程序:判断一个数组中的所有偶数并存放
			;入口参数:顺序压入数据个数 数据偏移地址
	push ebp	;将ebp入栈
	mov ebp,esp	;esp放入ebp中进行操作
	push ebx
	push edi
	push eax
	push ecx
	push edx	;保护寄存器
	mov ebx,[ebp+8]	;堆栈中取出的偏移地址
	mov ecx,[ebp+12];堆栈中取出数组个数
	xor esi,esi	;控制dat数组
	xor edi,edi	;控制p数组

start1:	cmp ecx,0
	jz done3
	xor edx,edx
	xor eax,eax
	mov dx,[ebx+esi*2]
	mov ax,dx
	and dx,01h
	cmp dx,01h
	jz odd
	mov p[edi*2],ax
	inc edi
odd:	dec ecx
	inc esi
	jmp start1

done3:	mov no,di
	pop edx
	pop ecx
	pop eax
	pop edi
	pop ebx
	pop ebp
	ret 8		;因为主程序压入两个参数,使用堆栈区8个字节	
judge	endp		;返回一个数组


output	proc		;子程序:数组输出程序
			;参数:相关待输出数组
	xor esi,esi
	xor ecx,ecx
	mov ecx,dword ptr no
	xor eax,eax
	mov eax,ecx
	call writeint
	call crlf

ha6:	cmp ecx,0
	jz done3
	xor eax,eax
	mov ax,p[esi*2]
	call writeint
	call crlf
	inc esi
	dec ecx
	jmp ha6
done3:	ret
output	endp		;无输出

	end main	;汇编结束
;总结:堆栈传递参数和其他的区别
;提前将数组的数量和偏移量入栈
;在最后要ret 8用于平衡堆栈
;其余的操作没有什么不一样
### 导入和配置ARM Compiler的步骤 #### 安装ARM Compiler 1. **下载安装包**:确保从可信来源获取ARM Compiler的安装包,例如ARM官方提供的资源。建议选择与Keil MDK兼容的版本,如ARM Compiler 5.06 [^1]。 2. **关闭Keil MDK**:在安装ARM Compiler之前,请确保Keil MDK软件完全关闭,以避免安装过程中出现冲突。 3. **执行安装**:双击下载的安装程序,遵循安装向导的指示进行安装。安装路径应选择在Keil的安装目录下的ARM文件夹内 [^2]。 #### 配置Keil MDK 1. **添加编译器版本**: - 在Keil中打开:`Project` -> `Manage` -> `Project Items` -> `Folders/Extensions`。 - 点击`...`按钮,选择`Add another Arm Compiler Version to List`。 - 选择上面配置的AC5安装路径 。 2. **验证安装**: - 打开项目,检查编译设置,确保使用的编译器版本正确。 - 进行小范围测试,确认无误后再全面应用到项目中 。 #### 编译器预定义 - **编译器版本检测**:在代码中使用预定义宏来检测编译器版本,以确保代码的兼容性。例如,使用`__ARMCC_VERSION`来判断是否为ARM Compiler 6: ```c #if defined __CC_ARM // Arm Compiler 5 #elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) // Arm Compiler 6 #elif defined __GNUC__ // Normal GCC #endif ``` #### 串口输出配置 - **retarget配置**:在Keil MDK中使用ARM Compiler 6时,retarget的配置与ARM Compiler 5类似: ```c int fputc(int ch, FILE *f) { return uartSendChar(ch); } int fgetc(FILE *f) { return uartReceiveChar(); } ``` - **printf警告处理**:当使用字符串变量作为`printf`的参数时,可能会遇到警告。建议改为使用格式化字符串: ```c char my_string[] = "message"; printf("%s", my_string); ``` #### 汇编代码兼容性 - **GNU风格汇编代码**:ARM Compiler 6开始支持GNU风格的汇编代码。例如: ```asm .section .text,"x" .balign 4 main: MOV w5, #0x64 MOV w4, #0 B test_loop loop: ADD w5, w5, #1 ADD w4, w4, #1 test_loop: CMP w4, #0xa BLT loop .end ``` ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值