【问题标题】:Assembler code, wrong value at entering code, factorial汇编代码,输入代码时的错误值,阶乘
【发布时间】:2013-03-19 17:31:10
【问题描述】:

这是我的完整代码:

SYSCALL = 0X80
STDIN = 0
STDOUT = 1
SYSREAD = 3
SYSWRITE = 4
SYSEXIT = 1

.section .data

WYBOR_MAXLEN = 2
WYBOR: .space WYBOR_MAXLEN
WYBOR_LEN: .byte


.section .text
.globl _start

_start:

mov $WYBOR_MAXLEN, %edx
mov $WYBOR, %ecx
mov $STDIN, %ebx
mov $SYSREAD, %eax
int $SYSCALL

movl $0, %edi
mov WYBOR(, %edi, 1), %al

pushl %eax
call silnia
addl $4, %esp
movl %eax, %ebx
movl $1, %eax
int $0x80

#To jest rzeczywista definicja funkcji
.type silnia, @function

silnia:

pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
cmpl $1, %eax
je end_silnia

decl %eax
pushl %eax
call silnia
movl 8(%ebp), %ebx
imull %ebx, %eax

end_silnia:
movl %ebp, %esp
popl %ebp
ret

我希望该程序运行并输入值以从中计算阶乘。我可以写值,但它会“分段错误”。如果我将 pushl $LOl 更改为 ecample pushl $4,它将计入正常阶乘。我可以更改代码以从我的键盘输入值来编程吗?

@编辑 我改变了这个片段:

movl $0, %edi
mov WYBOR(, %edi, 1), %al

pushl %eax

如果我在键盘上输入任何内容,它每次都会返回值“0”。

【问题讨论】:

  • STDIN 不需要为 1 才能使用键盘吗?抱歉,久违了。
  • 好吧,我可以把一个值从键盘输入到程序中。然后是分段错误。

标签: linux assembly x86 segmentation-fault push


【解决方案1】:

阶乘函数的退出条件是n == 1(其中n 是参数)。因此,如果您调用值为 0 的函数(就像您现在所做的那样,因为您已将 LOL 定义为 0),那么在 n 达到 1 之前需要很长时间(大约 40 亿次递归调用)。
在此之前,您的程序很可能会耗尽其分配的堆栈空间。

要么将退出条件更改为n <= 1,要么确保永远不会将 0 传递给函数。

【讨论】:

  • 你可能是对的,我真的不擅长汇编。我是这样看的:我创建了一个变量 LOL,将其设置为 0。然后我在键盘上输入例如“3”,它进入 ecx,我将其放入 eax,然后从 eax 我将它再次放入 LOL 中应该是 3。当然不是。请检查我更改的代码。 t 每次输入任何内容时都返回值“0”。
  • 我也将代码结尾更改为“cmpl $1, %eax jle end_silnia”,但仍然只重视 echo's me 是“0”
  • 还有更多我现在尝试输入简单数字的东西,比如 3/4/5。唯一的问题是“从键盘读取”可能不起作用,因为如果我将静态数字输入 pushl - 它会完美运行。
  • 我的答案是摆脱分段错误。为什么你的文本输入不起作用我不知道,但你真的应该检查每个系统调用的结果。例如,read 系统调用要么返回读取的字节数,要么返回 eax 中的错误代码。
  • 为什么我不能推送例如 (%ecx) 而不会出现分段失败错误?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多