IMUL指令寄存器
Registers for IMUL instruction
我正在编写这个简单的程序来计算递归序列的第 i 个元素。序列基本上看起来像
a(n)=a(n-1)*a(n-2)
前两个元素是-1和-3。我使用 imul
进行乘法运算,由于我在网上的发现,我应该可以使用我想要的任何寄存器,但对第三个元素编程 returns 0 。当切换到 add
时,它会按预期工作。
这是我递归调用函数并相乘的片段(如图所示,我使用堆栈来存储我的变量)
push %rcx
push %rax
call calculate
pop %rax
pop %rcx
imul %rcx, %rbx
基本上问题是 "why it doesn't work" :P
PS。如果需要完整代码:
.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 , %r8
push %r8 # push r8 (function argument) to stack
call calculate # call function to calculate
add , %rsp # removing parameter from stack
# now we should've have result in rbx
#
mov [=12=], %r15 # Flaga znaku (domyślnie 0 = +)
cmp [=12=], %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 , %r15 # Ustawienie flagi znaku na 1 = -.
to_ascii:
mov %rbx, %rax # result goes to rax
mov $OUTPUT_BASE, %rbx
mov [=12=], %rcx
jmp loop
loop:
mov [=12=], %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 [=12=], %rax
jne loop
jmp inverse
inverse:
mov [=12=], %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 [=12=], %r10 # want sign at the first position
movb $PLUS, znak(, %r10, 1)
cmp [=12=], %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 , %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 , %rsp
mov 16(%rbp), %rax
cmp , %rax
jl first
je second
mov [=12=], %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
您将 %rcx 设为零,然后乘以它,因此您的乘积始终为零。
也许你想改变
mov [=10=], %rcx
至
mov , %rcx
我觉得你还需要反转
imul %rcx, %rbx
至
imul %rbx, %rcx
(我不熟悉那种汇编程序的味道)
我正在编写这个简单的程序来计算递归序列的第 i 个元素。序列基本上看起来像
a(n)=a(n-1)*a(n-2)
前两个元素是-1和-3。我使用 imul
进行乘法运算,由于我在网上的发现,我应该可以使用我想要的任何寄存器,但对第三个元素编程 returns 0 。当切换到 add
时,它会按预期工作。
这是我递归调用函数并相乘的片段(如图所示,我使用堆栈来存储我的变量)
push %rcx
push %rax
call calculate
pop %rax
pop %rcx
imul %rcx, %rbx
基本上问题是 "why it doesn't work" :P
PS。如果需要完整代码:
.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 , %r8
push %r8 # push r8 (function argument) to stack
call calculate # call function to calculate
add , %rsp # removing parameter from stack
# now we should've have result in rbx
#
mov [=12=], %r15 # Flaga znaku (domyślnie 0 = +)
cmp [=12=], %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 , %r15 # Ustawienie flagi znaku na 1 = -.
to_ascii:
mov %rbx, %rax # result goes to rax
mov $OUTPUT_BASE, %rbx
mov [=12=], %rcx
jmp loop
loop:
mov [=12=], %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 [=12=], %rax
jne loop
jmp inverse
inverse:
mov [=12=], %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 [=12=], %r10 # want sign at the first position
movb $PLUS, znak(, %r10, 1)
cmp [=12=], %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 , %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 , %rsp
mov 16(%rbp), %rax
cmp , %rax
jl first
je second
mov [=12=], %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
您将 %rcx 设为零,然后乘以它,因此您的乘积始终为零。
也许你想改变
mov [=10=], %rcx
至
mov , %rcx
我觉得你还需要反转
imul %rcx, %rbx
至
imul %rbx, %rcx
(我不熟悉那种汇编程序的味道)