Primero escriba un archivo de código de lenguaje C mstore.c de la siguiente manera:
#include <stdio.h>
long mult2(long, long);
void multstore(long x, long y, long *dest) {
long t = mult2(x, y);
*dest = t;
}
Use la opción "-S" en la línea de comando para ver el código ensamblador generado por el compilador del lenguaje C:
PS E:\VS Code\VS Code C\chapter 3> gcc -S mstore.c
Esto hará que GCC ejecute el compilador y genere un archivo de ensamblaje mstore.s, pero no hará más trabajo. (Por lo general, continuará llamando al ensamblador para generar archivos de código objeto).
.file "mstore.c"
.text
.globl multstore
.def multstore; .scl 2; .type 32; .endef
.seh_proc multstore
multstore:
pushq %rbx
.seh_pushreg %rbx
subq $32, %rsp
.seh_stackalloc 32
.seh_endprologue
movq %r8, %rbx
call mult2
movl %eax, (%rbx)
addq $32, %rsp
popq %rbx
ret
.seh_endproc
.ident "GCC: (x86_64-posix-seh-rev0, Built by MinGW-W64 project) 8.1.0"
.def mult2; .scl 2; .type 32; .endef
Si continúa utilizando la opción de línea de comandos "-C", GCC compilará y ensamblará el código:
PS E:\VS Code\VS Code C\chapter 3> gcc -c mstore.c
Esto generará el archivo de código objeto mstore.o, que está en formato binario, por lo que no se puede ver directamente.
Para ver el contenido de un archivo de código de máquina, existe un programa llamado desensamblador que es muy útil. Estos programas generan un formato similar al ensamblaje basado en código máquina. El programa OBJDUMP (volcado de objeto) con el indicador de línea de comando "-d" puede desempeñar este papel:
PS E:\VS Code\VS Code C\chapter 3> objdump -d mstore.o
El resultado es el siguiente: Para
generar el código ejecutable real, el vinculador debe ejecutarse en un grupo de archivos de código objeto, y este grupo de archivos de código objeto debe contener una función principal. Supongamos que existe la siguiente función en el archivo main.c:
#include <stdio.h>
void multstore(long, long, long *);
int main() {
long d;
multstore(2, 3, &d);
printf("2 * 3 --> %ld\n", d);
return 0;
}
long mult2(long a, long b) {
long s = a * b;
return s;
}
Luego, use el siguiente método para generar el archivo ejecutable prog:
PS E:\VS Code\VS Code C\chapter 3> gcc -o prog main.c mstore.c
Por ejemplo, el
archivo prog no solo contiene el código de los dos procesos, sino que también contiene el código utilizado para iniciar y finalizar el programa, así como el código utilizado para interactuar con el sistema operativo. También podemos desmontar el archivo prog:
PS E:\VS Code\VS Code C\chapter 3> objdump -d prog.exe
En este punto, puede ejecutar el archivo prog generado: se
encuentra que los resultados de ejecución del programa de los dos archivos C están en línea con las expectativas.
En el archivo mstore.s generado:
todas las .
líneas que comienzan con ' ' son directivas para indicar al ensamblador y al enlazador que funcionen, normalmente podemos ignorar estas líneas. Si los eliminamos, el código ensamblador con explicación es el siguiente:
Tenga en cuenta que lo siguiente es el archivo mstore.s en el entorno Linux
multstore:
pushq %rbx
subq $32, %rsp
movq %r8, %rbx
call mult2
movl %eax, (%rbx)
addq $32, %rsp
popq %rbx
ret