trata - llamando a la función de ensamblaje desde c
video viral de la moto (3)
Intento llamar a una función de ensamblaje desde c, pero sigo recibiendo errores.
.text
.globl integrate
.type integrate, @function
integrate:
push %ebp
mov %esp, %ebp
mov $0,%edi
start_loop:
cmp %edi,1024
je loop_exit
mov 8(%ebp),%eax
mov 12(%ebp),%ecx
sub %eax,%ecx
add %edi,%ecx
incl %edi
jmp start_loop
loop_exit:
movl %ebp, %esp
popl %ebp
ret
Esta es mi función de ensamblaje, archivo llamado integrate.s.
#include <stdio.h>
extern int integrate(int from,int to);
void main()
{
printf("%d",integrate(1,10));
}
Aquí está mi código c
function.c:5:6: warning: return type of ‘main’ is not ‘int’ [-Wmain]
/tmp/cciR63og.o: In function `main'':
function.c:(.text+0x19): undefined reference to `integrate''
collect2: ld returned 1 exit status
Cada vez que trato de compilar mi código con la función gcc -Wall function.c -o, se obtiene el error "referencia no definida para integrar". También intenté agregar un enlace al archivo integrate.s de c, como
#include<(file path)/integrate.s>
pero tampoco funcionó. Lo que está haciendo el código ensamblador no es importante, por ahora estoy tratando de llamar a la función desde c con éxito. ¿Alguien puede ayudarme a resolver este problema?
advertencia: el tipo de devolución de ''main'' no es ''int''
significa que el tipo de retorno de ''main'' no es ''int'' ... Cámbielo a int
, luego:
int main()
{
}
Además, para resolver el error del enlazador, invoque a GCC como
gcc -o myprog main.c integrate.s
y eso debería funcionar
Veo los siguientes problemas con el código:
- llamando a los mandatos de la convención debes preservar el valor de
edi
-
cmp %edi,1024
está usando1024
como dirección y probablemente fallará. Quierecmp $1024,%edi
para comparar con un número inmediato - estás recargando
eax
yecx
de los argumentos de cada iteración para que el cálculo que realices no tenga ningún efecto - no parece poner ningún valor de retorno razonable en
eax
(devolverá el valor defrom
que se pasó)
Los dos primeros puntos se aplican incluso si "lo que está haciendo el código de ensamblaje no es importante".
No estoy seguro si ha resuelto esto o no, pero aquí es cómo lo he hecho.
Al compilar, asegúrese de agregar ambos archivos: $gcc main.c print_msg.s -o main
Para ejecutar el archivo ensamblador por su cuenta: $as print_msg.s -o print_msg.o
seguido de $ld print_msg.o -e print -o print_msg
. Tenga en cuenta que esto no es necesario si solo desea ejecutarlo desde su archivo C.
El archivo ensamblador: print_msg.s
# A program to be called from a C program
# Declaring data that doesn''t change
.section .data
string: .ascii "Hello from assembler/n"
length: .quad . - string
# The actual code
.section .text
.global print
.type print, @function #<-Important
print:
mov $0x1,%rax # Move 1(write) into rax
mov $0x1,%rdi # Move 1(fd stdOut) into rdi.
mov $string,%rsi # Move the _location_ of the string into rsi
mov length,%rdx # Move the _length_ of the string into rdx
syscall # Call the kernel
mov %rax,%rdi # Move the number of bytes written to rdi
mov $0x3c,%rax # Move 60(sys_exit) into rax
syscall # Call the kernel
luego el archivo C: main.c
extern void print(void);
int main(void)
{
print();
return 0;
}