要解决你的递归的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)相关推荐

  1. 知识库递归编程java和prolog代码;逻辑语言Prolog简介(附24555字PDF发“递归prolog简介”下载)

    知识库递归编程java和prolog代码:逻辑语言Prolog简介(附24555字PDF发"递归prolog简介"下载) 数据简化DataSimp 今天 数据简化DataSimp导 ...

  2. c语言递归函数变量作用域,C语言课程变量的作用域和生存周期、递归.ppt

    C语言课程变量的作用域和生存周期.递归 函数的定义和函数的调用 函数定义格式: 返回值类型 函数名(类型 参数1,类型 参数2,-) { 函数体 return 表达式; } 函数调用格式: 函数名(参 ...

  3. go channel 缓冲区最大限制_Go语言11周年,泛型问题有望明年得到解决

    作者 | 田晓旭.万佳 近日,Go 团队发布长篇博文庆祝 Go 语言开源 11 周年. Go 团队在博文写道,"回想 Go 语言十周年庆典恍如隔世.虽然 2020 年有诸多艰难,但我们一直在 ...

  4. Python语言importError:cannot import name ‘InvalidArgumentException‘报错的解决方法:

    Python语言importError:cannot import name 'InvalidArgumentException'报错的解决方法: 参考文章: (1)Python语言importErr ...

  5. 计算机语言安装不上,安装程序包的语言不受系统支持,详细教您如何解决Office2010安装时语言不受系统支持...

    由于不小心意外中断了卸载过程,结果怎么也卸载不掉office 2010了,但是文件关联彻底损坏了,导致用低版本也无法打开,而是遇到了安装时语言不受系统支持的情况,下面,小编就给大家分享解决Office ...

  6. c语言——程序出现C4996:scanf 等错误的解决方法

    c语言--程序出现C4996:scanf 等错误的解决方法(不用scanf_s替换解决) 问题实例 解决方法 方法1 方法2 在VS编译器下,编写的c语言程序在调试编译时可能会出现c4996警告或错误 ...

  7. 递归详解——让你真正明白递归的含义

    哈喽!这里是一只派大鑫,不是派大星.本着基础不牢,地动山摇的学习态度,从基础的C语言语法讲到算法再到更高级的语法及框架的学习.更好地让同样热爱编程(或是应付期末考试 狗头.jpg)的大家能够在学习阶段 ...

  8. sql表中只有子节点的递归_动态规划与静态规划、递归、分治、回溯

    动态规划算是运筹学或者算法中的硬骨头了.不是说算法本身有多难,而是学完用完之后还是感觉到对其领会的不够深入,一种能用其术,不知其道的感觉.在很多教材或者回答中,经常看多将动态规划放在递归这一部分中.当 ...

  9. ++递归 字符串全排列_超全递归技巧整理,这次一起拿下递归

    0. 前言 大家好,我是多选参数的程序锅,一个正在 neng 操作系统.学数据结构和算法以及 Java 的硬核菜鸡.本篇将主要介绍递归相关的内容,下面是本篇的内容提纲. 1. 递归基础 ★ 争哥:从我 ...

最新文章

  1. 超干货!一位博士生80篇机器学习相关论文及笔记下载
  2. 量子位「MEET 2022智能未来大会」启动,邀你一起见证AI价值
  3. 400名微软员工详细薪资信息泄露,资历和国籍对薪资影响巨大!
  4. mysql left day 7_day7-mysql函数
  5. 使用qsort对不连续的内存数据排序_常见的内排序和外排序算法
  6. Dapr + .NET 实战(九)本地调试
  7. JAVA使用FTPClient类读写FTP
  8. 状态模式java 在线投票_Java 状态模式
  9. 自学python 编程基础科学计算及数据分析 pdf_自学Python:编程基础、科学计算及数据分析...
  10. NFT推动全球加密艺术浪潮
  11. ios音乐播放器demo
  12. 字体大宝库:40款好看的英文手写字体下载
  13. 16秋计算机JAVA第一节课作业(钟永钜)
  14. ps人物碎片化飞溅效果特效怎么做
  15. 面试留“家庭作业”的公司,都TM是耍流氓!
  16. 硬件探索——2FSK通信系统调制解调综合实验电路设计
  17. 小迪渗透Waf绕过(陆)
  18. 手机上怎么照证件照照片?教你两招轻松拍出证件照
  19. java写华容道_基于java的华容道小游戏
  20. 实战 Java 第10天:商品分页查询

热门文章

  1. 广义状态平均法功率变换器建模分析
  2. hadoop新手入门指导
  3. 百度入局, 一文读懂年交易过4亿「超级链」究竟是什么?
  4. Unity SpriteRender 和Image的区别
  5. FIRST集、FOLLOW集和SELECT集
  6. 03@Dockerfile构建镜像
  7. 电脑c盘满了怎么清理 c盘哪些文件可以删除
  8. SPARK-SQL 读取 内存table 或 hive中的table
  9. C1认证学习八(域名解析)
  10. MySQL之ANALYZE TABLE