MASM汇编:如何交换数组相邻元素并实现十进制输出
解决MASM中WORD数组相邻交换与十进制输出的问题
嘿,作为MASM新手,你已经找对了大致方向,咱们一步步解决你的两个核心问题,同时修正代码里的小错误:
问题1:如何把edi的值放入16位寄存器?
其实在32位x86汇编里,edi是32位寄存器,它的低16位对应16位寄存器di——所以如果你只是需要edi里的16位数据,直接用di就行,或者用mov bx, di把低16位复制到bx里。不过针对你的WORD数组操作,其实更推荐直接用16位寄存器(比如si、di、bx)来处理,因为数组元素是16位的,这样操作更简洁,没必要动用32位的edi(除非你需要32位的地址,但这里数组偏移用si足够了)。
问题2:十进制输出交换后的数组
Irvine32库的WriteDec函数要求把要输出的无符号数放在32位寄存器eax里。因为你的数组元素是16位WORD类型,所以需要用movzx指令(无符号扩展)把16位的值扩展成32位,再放到eax里,然后调用WriteDec。另外需要循环遍历整个数组,逐个输出元素,还可以加个空格分隔让输出更清晰。
修正后的完整代码
咱们把你的代码调整一下,修复交换逻辑,同时加上输出部分:
TITLE ArrayCode INCLUDE Irvine32.inc .DATA warray WORD 4,9,13,7,5,12,17,2,15,8 outputMsg BYTE "交换后的数组:",0ah,0dh,0 ; 换行提示信息 .CODE main PROC ; 第一步:执行相邻元素两两交换 xor eax, eax xor ebx, ebx mov esi, OFFSET warray ; esi指向数组起始地址 mov ecx, 5 ; 10个元素,共5对需要交换 L1: mov ax, [esi] ; 取当前元素到ax(第1/3/5...个元素) mov bx, [esi+2] ; 取下一个相邻元素到bx(第2/4/6...个元素) mov [esi], bx ; 交换:把bx的值存到当前位置 mov [esi+2], ax ; 把ax的值存到下一个位置 add esi, 4 ; 移动到下一对元素(每个WORD占2字节,一对是4字节) loop L1 ; 第二步:输出交换后的数组 mov edx, OFFSET outputMsg call WriteString ; 输出提示信息 mov esi, OFFSET warray ; 重置esi到数组开头 mov ecx, 10 ; 数组共10个元素 L2: movzx eax, [esi] ; 把16位WORD无符号扩展到32位eax call WriteDec ; 输出十进制数 mov al, ' ' ; 输出空格分隔元素 call WriteChar add esi, TYPE warray ; 移动到下一个元素(TYPE warray=2) loop L2 call Crlf ; 换行 call WaitMsg EXIT main ENDP end main
关键细节解释
- 交换逻辑:原来的代码里
add esi, TYPE warray只移动了2字节,会导致重复处理元素,改成add esi,4后,每次跳过一对元素(4字节),刚好处理5对。 - 输出时的
movzx:因为WriteDec需要32位的eax,而数组元素是16位,用movzx可以确保无符号数的正确扩展(比如如果元素是0xFFFF,扩展后是0xFFFFFFFF,而如果用mov的话会把eax的高16位保留原来的值,导致错误)。 - 输出提示和空格:让输出结果更易读,符合常规的控制台输出习惯。
内容的提问来源于stack exchange,提问作者Alejandro Harrison
相关产品推荐
相关产品推荐

