0

ここに私の完全なコードがあります:

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 に変更すると、通常の階乗がカウントされます。コードを変更してキーボードからプログラムに値を入力できますか?

@edit このフラグメントを変更しました:

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

pushl %eax

キーボードで何かを入力すると、毎回値「0」が返されます。

4

1 に答える 1

0

階乗関数の終了条件はn == 1(nは引数) です。そのため、値 0 で関数を呼び出すと (0 と定義したため、今のLOLように) 1 に達するまでに非常に長い時間がかかりますn(約 40 億回の再帰呼び出し)。
あなたのプログラムは、それが起こる前に割り当てられたスタックスペースを使い果たす可能性が非常に高い.

終了条件を に変更するかn <= 1、関数に 0 を渡さないようにしてください。

于 2013-03-19T18:29:21.247 に答える