Suma C code:
#include <stdio.h>
int main ()
{
int a = 3, b = 4;
int c = a+b;
printf("La suma da: %d\n",c);
return 0;
}
.file "holamundo.c"
.intel_syntax noprefix
.text
.section .rodata
.LC0:
.string "La suma da: %d\n"
.text
.globl "main"
.type "main", @function
"main":
.LFB0:
.cfi_startproc
push rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
mov rbp, rsp
.cfi_def_cfa_register 6
sub rsp, 16 // Pide espacio para las variables. 16 bytes = 128 bits.
// RSP = SP = stack pointer = puntero de pila.
// sub le resta 16 bytes porque declaré 3 variables int.
// Cada int tiene 4 bytes.
// LA PILA CRECE HACIA ARRIBA.
// Primero pide 16 bytes.
// A 16 bytes - 12 bytes = 4 bytes.
// 12 bytes - 8 bytes = 4 bytes
// 12 bytes - 8 bytes = 4 bytes
// 8 bytes - 4 bytes = 4 bytes
// Un int son 4 bytes (en 64 bits)
mov DWORD PTR -12[rbp], 3 // 12 bytes = 96 bits DWORD = 16 bits
mov DWORD PTR -8[rbp], 4 // 8 bytes = 64 bits.
mov edx, DWORD PTR -12[rbp] // El DX se usa como 2do acumulador?
mov eax, DWORD PTR -8[rbp]
add eax, edx
mov DWORD PTR -4[rbp], eax
mov eax, DWORD PTR -4[rbp]
lea rdx, .LC0[rip]
mov esi, eax // ESI o RSI es el 2do argumento de la función
mov rdi, rdx // EDI RDI es el 1er argumento
mov eax, 0
call "printf"@PLT
mov eax, 0
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size "main", .-"main"
.ident "GCC: (GNU) 16.1.1 20260625"
.section .note.GNU-stack,"",@progbits
nasm -f elf64 suma.asm -o suma.o gcc suma.o -o suma
section .data
LC0 db "La suma da: %d", 10, 0
section .text
global main
extern printf
main:
push rbp
mov rbp, rsp
sub rsp, 16
; Asignar valores a las variables
mov DWORD [rbp-12], 3 ; int a = 3
mov DWORD [rbp-8], 4 ; int b = 4
; Sumar a + b
mov edx, DWORD [rbp-12] ; edx = a
mov eax, DWORD [rbp-8] ; eax = b
add eax, edx ; eax = a + b
mov DWORD [rbp-4], eax ; resultado = eax
; Preparar llamada a printf
mov eax, DWORD [rbp-4] ; eax = resultado
lea rdi, [rel LC0] ; primer argumento: formato
mov esi, eax ; segundo argumento: resultado
mov eax, 0 ; sin registros XMM
call printf WRT ..plt
; Retornar 0
mov eax, 0
leave
ret
WRT = “With Respect To” (con respecto a)
..plt = sección PLT en el ejecutable
Le dice al enlazador: “usa la entrada PLT de printf”
call printf ; ❌ ERROR: El enlazador no sabe dónde está printf
call printf WRT ..plt ; ✅ Usa la tabla PLT
extern printf
call printf wrt ..plt