汇编实现斐波那契序列时,10-15求和自动转十六进制的问题求助
实现带格式转换的15项斐波那契序列(x86汇编)
根据你的需求,核心是用eax和ebx生成斐波那契数,并在数值处于10-15区间时输出十六进制格式,其余情况输出十进制。下面分两种场景给出实现方案:
场景1:纯汇编(无C库依赖,Linux 32位 NASM)
适合要求纯汇编实现的作业场景,需自行实现数值转ASCII和输出逻辑:
section .data newline db 0xA ; 换行符 hex_buf db '0X' ; 十六进制格式缓冲区(0+字符) section .text global _start _start: mov ecx, 15 ; 生成15个数,计数器初始化为15 mov eax, 0 ; 斐波那契第1项 mov ebx, 1 ; 斐波那契第2项 fib_generator: ; 输出当前eax的值 push ecx ; 保存计数器,避免被输出函数修改 call print_formatted pop ecx ; 更新斐波那契连续项 mov edx, eax ; 暂存当前eax的值 mov eax, ebx ; eax替换为原ebx的值 add ebx, edx ; ebx更新为原eax+原ebx的和 dec ecx jnz fib_generator ; 计数器不为0则继续循环 ; 程序退出 mov eax, 1 xor ebx, ebx int 0x80 ; 格式化输出函数:判断数值范围,选择输出格式 print_formatted: ; 判断是否在10-15之间 cmp eax, 10 jl print_decimal cmp eax, 15 jg print_decimal ; 输出十六进制(如0D) mov byte [hex_buf], '0' ; 将数值转为A-F的ASCII字符 sub eax, 10 add eax, 'A' mov byte [hex_buf+1], al ; 输出十六进制字符串 mov ecx, hex_buf mov edx, 2 mov ebx, 1 mov eax, 4 int 0x80 call print_newline ret print_decimal: ; 十进制转ASCII并输出(简化实现) push ebx push ecx push edx xor ecx, ecx ; 统计数字位数 dec_to_ascii: xor edx, edx mov ebx, 10 div ebx ; eax=商,edx=余数 add edx, '0' push edx ; 余数入栈(逆序存储) inc ecx test eax, eax jnz dec_to_ascii dec_output: pop edx mov [newline], dl ; 临时存储字符 mov ecx, newline mov edx, 1 mov ebx, 1 mov eax, 4 int 0x80 dec ecx jnz dec_output pop edx pop ecx pop ebx call print_newline ret print_newline: ; 输出换行符 mov ecx, newline mov edx, 1 mov ebx, 1 mov eax, 4 int 0x80 ret
代码说明
- 斐波那契生成:通过
edx暂存寄存器值,实现eax和ebx的连续项更新,避免覆盖数据 - 格式判断:在
print_formatted中通过cmp指令判断数值范围,分支处理输出格式 - 十六进制转换:10-15减去10后加
'A',直接转为ASCII字符,配合前缀0输出 - 十进制转换:通过除法取余将数值转为逆序的ASCII字符,再通过栈反转顺序输出
场景2:汇编调用C库函数(更简洁,适合允许混合编程的作业)
如果作业允许调用C标准库(比如printf),代码会大幅简化,无需自行实现复杂的输出逻辑:
extern printf section .data fmt_dec db "%d", 0xA, 0 ; 十进制输出格式 fmt_hex db "0%X", 0xA, 0 ; 十六进制输出格式(带0前缀) section .text global main main: mov ecx, 15 ; 计数器:15个数 mov eax, 0 ; 斐波那契第1项 mov ebx, 1 ; 斐波那契第2项 loop: ; 判断数值范围,选择输出格式 cmp eax, 10 jl print_dec cmp eax, 15 jg print_dec ; 输出十六进制 push eax push fmt_hex call printf add esp, 8 jmp update_fib print_dec: ; 输出十进制 push eax push fmt_dec call printf add esp, 8 update_fib: ; 更新斐波那契项 mov edx, eax mov eax, ebx add ebx, edx dec ecx jnz loop ; 退出程序 mov eax, 0 ret
代码说明
- 直接调用
printf函数,通过格式字符串fmt_dec和fmt_hex分别处理十进制和十六进制输出 - 寄存器操作逻辑和纯汇编一致,重点简化了输出部分的代码
- 编译时需要链接C库:
nasm -f elf32 fib.asm && gcc -m32 fib.o -o fib
关键注意点
- 斐波那契序列的初始项可以根据需求调整(比如从1,1开始而非0,1),只需修改
eax和ebx的初始值 - 十六进制输出的前缀
0是需求明确要求的,所以在格式中固定添加 - 如果是Windows平台的MASM汇编,需要调整系统调用或库函数调用方式(比如用
invoke printf)
内容的提问来源于stack exchange,提问作者vanderbilt
相关产品推荐
相关产品推荐

