从汇编中调用C函数 - 应用程序冻结在"call printf",我不知道为什么

Dav*_*idH 6 assembly printf

我将参与一个大型的大会项目,但现在我刚开始学习这种新语言.我试图做一些简单的例子,比如你可能在highschool找到c ++(总和两个数字,是数字素数等).

现在我必须显示所有素数到n.问题是应用程序冻结在"call printf",我不明白为什么.

你能帮帮我吗?

.section    .data
prime_number_str:
.asciz  "%d "

.section    .text

.global     _start
_start:
pushl   $20
call .first_prime_numbers
addl $4, %esp
pushl $0
call exit


.first_prime_numbers:       #argument first n numbers
movl 4(%esp), %ecx  #get the first argument
do_test:
pushl %ecx      #push function arguments
call .prime 
addl $4, %esp       #restore the stack

#if not prime jump to the next number   
cmpl $0, %eax
je no_not_prime

#print the number
pushl %eax          #save eax
pushl %ecx          #first argument
pushl $prime_number_str     #text to print
call printf
addl $4, %esp
popl %eax           #restore eax

no_not_prime:
loop do_test
ret


.prime:             #argument: number to check
movl 4(%esp), %eax  #get the first argument

#divide the argument by 2   
xorl %edx, %edx             
movl $2, %ecx           
pushl %eax      #save the value of eax
divl %ecx       
movl %eax, %ecx     #init the counter register
popl %eax       #restore the value of eax

movl $1, %ebx       #assume the argument is prime
test_prime:
# if ecx == 1 then return exit the function
cmpl $1, %ecx       
jle return_value

pushl %eax      #save the old value of eax  

#divide the value by the value of counter   
xorl %edx, %edx     
divl %ecx       

#if the reminder is 0 then the number is not prime
cmpl $0, %edx   
popl %eax       #restore the value of eax   
je not_prime


subl $1, %ecx       #decrease counter
jmp test_prime      #try next division

not_prime:
movl $0, %ebx
return_value:
movl %ebx, %eax
ret 
Run Code Online (Sandbox Code Playgroud)

Fil*_*erg 4

可能是因为调用后你的寄存器都乱了printf,你需要保存你以后经常使用的寄存器printf,然后在调用后恢复它们。

当您这样做syscall或其他可能会篡改您的寄存器的调用时,您应该始终执行此操作。

另外你应该看看gdb(gnu调试器)看起来你正在编码GAS,所以如果你在gnu / linux系统上尝试:

gdb youprogram
Run Code Online (Sandbox Code Playgroud)

然后运行看看哪里失败了。