C语言递归解决杨辉三角,在大会递归解决杨辉三角(NCK)
要解决你的递归的combi:的中间部分有一个问题:
...
call combi
pop cx ;stores to cx popped value combi(n-1,k)
;*^this freed the allocated space for result
mov ebp, esp ;update pointers
;* not needed, as you will not use EBP right now, and next call destroys it
;combi(n-1,k-1)
push ax
;*^pushing first argument, but no stack space reserved for result
dec bx
push bx
call combi
...
为
修复你可以调整部分:
编辑:这不会为2+正常工作深递归,因为你需要不保留寄存器,整个递归结构需要更多的关心,我会简单地选择在第一位置更简单的设计,重写一遍,不是解决这些小问题。这个“修复”至少可以阻止部分违约行为。
...
call combi
mov cx,[esp] ;stores to cx value combi(n-1,k)
;*^keeps the stack space reserved (not popping)
;combi(n-1,k-1)
push ax
...
当然还有其他问题,您的输出是只为单个数字是正确的,但只是搜索堆栈溢出,tag [x86] info对于那些不打算在这里重复。
顺便说一句,这IMO从不幸的过于复杂的使用堆栈茎,你有你为什么遵循这样复杂的调用约定一些特别的原因吗?如何在自定义快速调用类似的参数和结果寄存器?它的性能也更高,但对我个人而言,跟踪事情并正确处理堆栈也更容易。如果我会尝试......我可以在以后的版本中添加我自己的变体。
编辑:
文件:用寄存器调用约定全面工作示例so_32b_pascal_triangle.asm
section .text
global _start
_start:
mov ecx,5 ; n
mov edx,2 ; k
call combi
; return to linux with sys_exit(result)
mov ebx,eax
mov eax,1
int 80h
; ECX = n, EDX = k, returns result in EAX, no other register modified
; (_msfastcall-like convention, but extended to preserve ECX+EDX)
combi: ; c(n, k) = c(n-1, k-1) + c(n-1, k), c(i, 0) = c(i, i) = 1
test edx,edx ; k == 0
je .basecases ; c(i, 0) = 1
cmp edx,ecx ; k == n
je .basecases ; c(i, i) = 1
; 0 < k < n case:
dec ecx ; n-1
call combi ; EAX = c(n-1, k)
push esi
mov esi,eax ; keep c(n-1, k) in ESI
dec edx ; k-1
call combi ; EAX = c(n-1, k-1)
add eax,esi ; EAX = c(n-1, k-1) + c(n-1, k)
; restore all modified registers
pop esi
inc ecx
inc edx
ret ; return result in EAX
.basecases:
mov eax,1
ret
编译+运行+显示结果:
...$ nasm -f elf32 -F dwarf -g so_32b_pascal_triangle.asm -l so_32b_pascal_triangle.lst -w+all
...$ ld -m elf_i386 -o so_32b_pascal_triangle so_32b_pascal_triangle.o
...$ ./so_32b_pascal_triangle ; echo $?
10
...$
编辑:
而对于我自己的好奇心,试图把它从C-ISH C++代码(验证fastcall约定按预期工作需要与C/C++的互操作性,即使):
该so_32b_pascal_triangle.asm文件具有相同combi:代码,但开始时修改(添加全球,除去_start):
section .text
global combi
; ECX = n, EDX = k, returns result in EAX, no other register modified
; (fastcall-like convention, but extended to preserve ECX+EDX)
combi: ; c(n, k) = c(n-1, k-1) + c(n-1, k), c(i, 0) = c(i, i) = 1
...
文件so_32b_pascal_triangle_Cpp.cpp:
#include
#include
extern "C" __attribute__ ((fastcall)) uint32_t combi(uint32_t n, uint32_t k);
int main()
{
for (uint32_t n = 0; n < 10; ++n) {
printf("%*c", 1+2*(10-n), ' ');
for (uint32_t k = 0; k <= n; ++k) {
printf("%4d", combi(n, k));
// 4-char width formatting - works for 3 digit results max.
}
printf("\n");
}
}
生成+测试:
$ nasm -f elf32 -F dwarf -g so_32b_pascal_triangle.asm -l so_32b_pascal_triangle.lst -w+all
$ g++ -std=c++17 -c -m32 -O3 -Wall -Wpedantic -Wextra so_32b_pascal_triangle_Cpp.cpp
$ g++ -m32 so_32b_pascal_triangle*.o -o so_32b_pascal_triangle
$ ./so_32b_pascal_triangle
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
1 9 36 84 126 126 84 36 9 1
C语言递归解决杨辉三角,在大会递归解决杨辉三角(NCK)相关推荐
- 知识库递归编程java和prolog代码;逻辑语言Prolog简介(附24555字PDF发“递归prolog简介”下载)
知识库递归编程java和prolog代码:逻辑语言Prolog简介(附24555字PDF发"递归prolog简介"下载) 数据简化DataSimp 今天 数据简化DataSimp导 ...
- c语言递归函数变量作用域,C语言课程变量的作用域和生存周期、递归.ppt
C语言课程变量的作用域和生存周期.递归 函数的定义和函数的调用 函数定义格式: 返回值类型 函数名(类型 参数1,类型 参数2,-) { 函数体 return 表达式; } 函数调用格式: 函数名(参 ...
- go channel 缓冲区最大限制_Go语言11周年,泛型问题有望明年得到解决
作者 | 田晓旭.万佳 近日,Go 团队发布长篇博文庆祝 Go 语言开源 11 周年. Go 团队在博文写道,"回想 Go 语言十周年庆典恍如隔世.虽然 2020 年有诸多艰难,但我们一直在 ...
- Python语言importError:cannot import name ‘InvalidArgumentException‘报错的解决方法:
Python语言importError:cannot import name 'InvalidArgumentException'报错的解决方法: 参考文章: (1)Python语言importErr ...
- 计算机语言安装不上,安装程序包的语言不受系统支持,详细教您如何解决Office2010安装时语言不受系统支持...
由于不小心意外中断了卸载过程,结果怎么也卸载不掉office 2010了,但是文件关联彻底损坏了,导致用低版本也无法打开,而是遇到了安装时语言不受系统支持的情况,下面,小编就给大家分享解决Office ...
- c语言——程序出现C4996:scanf 等错误的解决方法
c语言--程序出现C4996:scanf 等错误的解决方法(不用scanf_s替换解决) 问题实例 解决方法 方法1 方法2 在VS编译器下,编写的c语言程序在调试编译时可能会出现c4996警告或错误 ...
- 递归详解——让你真正明白递归的含义
哈喽!这里是一只派大鑫,不是派大星.本着基础不牢,地动山摇的学习态度,从基础的C语言语法讲到算法再到更高级的语法及框架的学习.更好地让同样热爱编程(或是应付期末考试 狗头.jpg)的大家能够在学习阶段 ...
- sql表中只有子节点的递归_动态规划与静态规划、递归、分治、回溯
动态规划算是运筹学或者算法中的硬骨头了.不是说算法本身有多难,而是学完用完之后还是感觉到对其领会的不够深入,一种能用其术,不知其道的感觉.在很多教材或者回答中,经常看多将动态规划放在递归这一部分中.当 ...
- ++递归 字符串全排列_超全递归技巧整理,这次一起拿下递归
0. 前言 大家好,我是多选参数的程序锅,一个正在 neng 操作系统.学数据结构和算法以及 Java 的硬核菜鸡.本篇将主要介绍递归相关的内容,下面是本篇的内容提纲. 1. 递归基础 ★ 争哥:从我 ...
最新文章
- 超干货!一位博士生80篇机器学习相关论文及笔记下载
- 量子位「MEET 2022智能未来大会」启动,邀你一起见证AI价值
- 400名微软员工详细薪资信息泄露,资历和国籍对薪资影响巨大!
- mysql left day 7_day7-mysql函数
- 使用qsort对不连续的内存数据排序_常见的内排序和外排序算法
- Dapr + .NET 实战(九)本地调试
- JAVA使用FTPClient类读写FTP
- 状态模式java 在线投票_Java 状态模式
- 自学python 编程基础科学计算及数据分析 pdf_自学Python:编程基础、科学计算及数据分析...
- NFT推动全球加密艺术浪潮
- ios音乐播放器demo
- 字体大宝库:40款好看的英文手写字体下载
- 16秋计算机JAVA第一节课作业(钟永钜)
- ps人物碎片化飞溅效果特效怎么做
- 面试留“家庭作业”的公司,都TM是耍流氓!
- 硬件探索——2FSK通信系统调制解调综合实验电路设计
- 小迪渗透Waf绕过(陆)
- 手机上怎么照证件照照片?教你两招轻松拍出证件照
- java写华容道_基于java的华容道小游戏
- 实战 Java 第10天:商品分页查询