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;
}

INTEL ASM (gcc suma.c -c -S -masm=intel)

    .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

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

¿Qué hace WRT ..plt en el printf?

WRT = “With Respect To” (con respecto a)

..plt = sección PLT en el ejecutable

Le dice al enlazador: “usa la entrada PLT de printf”

  1. Sin WRT ..plt (versión incorrecta):
call printf  ; ❌​ ERROR: El enlazador no sabe dónde está printf
  1. Con WRT ..plt (versión correcta):
call printf WRT ..plt  ; ✅​ Usa la tabla PLT
  1. Alternativa más común (recomendada):
extern printf
call printf wrt ..plt