问题描述
我是汇编语言的新手。我正在用AT&T x64 / GNU语法创建素数分解函数。
这是..
.data
.text
.global main
.prime_end: .string "End\n"
.fact_end: .string "Finish\n"
.fact_print: .string "%d\n"
prime:
mov %rsi,%rax
mov $0,%rdi
cmp $2,%rax
jl prime_end
jmp prime_base
prime_base: # r10 = 1
mov $1,%r10
jmp prime_start
prime_start: # r10 + 1 = 2
inc %r10
jmp prime_check
prime_check:
cqto
div %r10 # rsi = 10,rax = 10,rax / r10 = 10/2
cmp $0,%rdx # rdx = 0,rax = 5
jne prime_start
jmp fact_check
fact_check: # rsi = 10,rax = 10
mov %rsi,%rax
cqto
div %r10 # 10 / 2
jmp prime_fact
prime_fact:
cmp %r10,%rax # to end function
jl fact_end
call fact_print # where I think it should be printed
mov %rax,%rsi # rax = 5,rsi = 5
add %rdx,%rsi # rdx = 0,rsi = 5
cmp $1,%rsi # if 5 = 1,end function
jne prime_base
jmp fact_end
fact_print:
mov $.fact_print,%rdi
mov %r10,%rsi
xor %rax,%rax
call printf
ret
fact_end:
mov $.fact_end,%rdi
xor %rax,%rax
call printf
ret
prime_end:
mov $.prime_end,%rax
call printf
ret
main:
mov $10,%rsi # check 10 ... expect 2 5
call prime
当我尝试打印素数分解数时,它说
2 2 2 2 2 2 2 2 ...
对不起。我很新。您能解释一下为什么只打印两次吗?要打印素因数分解,我该怎么办?
解决方法
fact_print
的调用者假定eax
寄存器不会被更改,但事实并非如此。返回fact_print
时,eax
将具有printf
返回的值(输出的字符数)。
您将需要在调用eax
之前将fact_print
存储在某个地方(未修改的寄存器中,或放在堆栈中),然后在返回时将其恢复。