2017-05-20 3 views
1

Ich schrieb dieses einfache Programm, um ein i-tes Element einer rekursiven Sequenz zu berechnen. Die Reihenfolge sieht grundsätzlich wie folgt aus:Register für IMUL-Befehl

a(n)=a(n-1)*a(n-2) 

mit den ersten beiden Elementen -1 und -3. Ich verwende imul zum Multiplizieren und aufgrund meiner Ergebnisse im Netz sollte ich in der Lage sein, alle gewünschten Register zu verwenden, aber das Programm gibt 0 für das dritte Element zurück. Bei Umschaltung auf add funktioniert es wie vorgesehen. Hier ist das Fragment, wo ich die Funktion rekursiv aufrufen und sich vermehren (wie gesehen, ich Stack verwenden, um meine Variablen zu speichern)

push %rcx 
push %rax 
call calculate 
pop %rax 
pop %rcx 
imul %rcx, %rbx 

Grundsätzlich Frage „warum es nicht funktioniert“: P

PS. Falls vollständiger Code benötigt:

.data 
STDOUT = 1 
SYSWRITE = 1 
HOW_MANY = 3    # which number to calculate 
SYSEXIT = 60 
EXIT_SUCCESS = 0 
FIRST = -1     # first element of the sequence 
SECOND = -3     # second element of the sequence 
NUMBER_BEGIN = 0x30 
OUTPUT_BASE = 10 
NEW_LINE = '\n' 
PLUS = '+' 
MINUS = '-' 

.bss 
.comm textin, 512 
.comm textout, 512 
.comm text2, 512 
.comm znak, 1 

.text 
.globl _start 

_start: 

# 
# Calling function to calculate ith element 
# 
mov $HOW_MANY, %r8 
sub $1, %r8 
push %r8     # push r8 (function argument) to stack 
call calculate    # call function to calculate 
add $8, %rsp    # removing parameter from stack 

# now we should've have result in rbx 
# 
mov $0, %r15 # Flaga znaku (domyślnie 0 = +) 
cmp $0, %rbx 
jge to_ascii # Pomiń jeśli liczba jest dodatnia 
not %rbx # Odwrócenie bitów liczby i dodanie 1, 
inc %rbx # aby uzyskać jej wartość bezwzględną. 
mov $1, %r15 # Ustawienie flagi znaku na 1 = -. 

to_ascii: 
mov %rbx, %rax # result goes to rax 
mov $OUTPUT_BASE, %rbx 
mov $0, %rcx 
jmp loop 

loop: 
mov $0, %rdx 
div %rbx # divide rax by rbx, rest in rdx 
add $NUMBER_BEGIN, %rdx # rest in rdx is a next position number 
mov %dl, text2(, %rcx, 1) 

inc %rcx 
cmp $0, %rax 
jne loop 
jmp inverse 

inverse: 
mov $0, %rdi 
mov %rcx, %rsi 
dec %rsi 
jmp inversev2 

inversev2: 
mov text2(, %rsi, 1), %rax 
mov %rax, textout(, %rdi, 1) 
inc %rdi 
dec %rsi 
cmp %rcx, %rdi 
jle inversev2 

push %rcx # legth of the answer goes to stack 

mov $0, %r10 # want sign at the first position 
movb $PLUS, znak(, %r10, 1) 

cmp $0, %r15 # r15 register contains info about the sign 
je next # 0 = +, so nothing has to be done 

movb $MINUS, znak(, %r10, 1) # otherwise set it to minus 

next: # show sign 
mov $SYSWRITE, %rax 
mov $STDOUT, %rdi 
mov $znak, %rsi 
mov $1, %rdx 
syscall 

pop %rcx 

movb $NEW_LINE, textout(, %rcx, 1) 
inc %rcx 

mov $SYSWRITE, %rax 
mov $STDOUT, %rdi 
mov $textout, %rsi 
mov %rcx, %rdx 
syscall 

mov $SYSEXIT, %rax 
mov $EXIT_SUCCESS, %rdi 
syscall 

# recursive function calculating ith element of a given sequence 
# sequence = 
# n_1 = -1 
# n_2 = -3 
# n_i = n_(i-1)*n_(i-2) 
calculate: 
push %rbp     # push rbp to stack to save it's value 
mov %rsp, %rbp    # now stack pointer is stored in rbp 

sub $8, %rsp 
mov 16(%rbp), %rax 

cmp $1, %rax 
jl first 
je second 

mov $0, %rcx 

# wywołanie dla n_(i-1) 
dec %rax 

push %rcx 
push %rax 
call calculate 
pop %rax 
pop %rcx # przepisać na rejestry imula 
imul %rcx, %rbx 

# wywołanie dla n_(i-2) 
dec %rax 
push %rcx 
push %rax 
call calculate 
pop %rax 
pop %rcx 
imul %rcx, %rbx 

return: 
mov %rcx, %rbx 
mov %rbp, %rsp 
pop %rbp 
ret 

first: 
mov $FIRST, %rbx 
mov %rbp, %rsp 
pop %rbp 
ret 

second: 
mov $SECOND, %rbx 
mov %rbp, %rsp 
pop %rbp 
ret 
+0

Bitte posten Sie den vollständigen Code inline in Ihrer Frage. – fuz

+0

Da gehen Sie hin. Ich dachte, es wird die Frage kürzer machen, wenn ich einen Link zu Pastebin einfügen – Wylfryd

Antwort

3

Du Impfen% rcx auf Null, dann in die Multiplikation, so dass Sie immer ein Produkt von Null haben.

Vielleicht möchten Sie

mov $0, %rcx 

zu

mov $1, %rcx 

Ich denke, ändern umkehren müssen Sie auch die

imul %rcx, %rbx 

zu

imul %rbx, %rcx 

(Ich bin nicht vertraut mit diesem Geschmack von Assembler)

+0

Ich fühle mich wie ein Idiot jetzt ... -.- Vielen Dank! – Wylfryd

+0

Und ja, ich habe das schon geändert, weil ich möchte, dass mein Ergebnis in '% rcx' und nicht '% rbx' steht – Wylfryd