Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

234
Vistas
¿Por qué gcc pasa el tipo de char en formato de 8 bytes al ensamblado de funciones?

Para aprender a ensamblar, estoy viendo el ensamblado generado por GCC usando el comando -S para algunos programas c simples. Tengo una función de agregar que acepta algunos enteros y algunos caracteres y los suma. Me pregunto por qué los parámetros char se insertan en la pila como 8 bytes (pushq). ¿Por qué no simplemente empujar un solo byte?

 .file "test.c" .text .globl add .type add, @function add: .LFB0: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 movl %edi, -4(%rbp) movl %esi, -8(%rbp) movl %edx, -12(%rbp) movl %ecx, -16(%rbp) movl %r8d, -20(%rbp) movl %r9d, -24(%rbp) movl 16(%rbp), %ecx movl 24(%rbp), %edx movl 32(%rbp), %eax movb %cl, -28(%rbp) movb %dl, -32(%rbp) movb %al, -36(%rbp) movl -4(%rbp), %edx movl -8(%rbp), %eax addl %eax, %edx movl -12(%rbp), %eax addl %eax, %edx movl -16(%rbp), %eax addl %eax, %edx movl -20(%rbp), %eax addl %eax, %edx movl -24(%rbp), %eax addl %eax, %edx movsbl -28(%rbp), %eax addl %eax, %edx movsbl -32(%rbp), %eax addl %eax, %edx movsbl -36(%rbp), %eax addl %edx, %eax popq %rbp .cfi_def_cfa 7, 8 ret .cfi_endproc .LFE0: .size add, .-add .globl main .type main, @function main: .LFB1: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 pushq $9 pushq $8 pushq $7 movl $6, %r9d movl $5, %r8d movl $4, %ecx movl $3, %edx movl $2, %esi movl $1, %edi call add addq $24, %rsp leave .cfi_def_cfa 7, 8 ret .cfi_endproc .LFE1: .size main, .-main .ident "GCC: (Ubuntu 4.9.2-10ubuntu13) 4.9.2" .section .note.GNU-stack,"",@progbits
 #include <stdio.h> int add(int a, int b, int c, int d, int e, int f, char g, char h, char i) { return a + b + c + d + e + f + g + h + i; } int main() { return add(1, 2, 3, 4, 5, 6, 7, 8, 9); }
over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

Es así porque el SystemV ABI x86-64 lo requiere.

Consulte https://github.com/hjl-tools/x86-psABI/wiki/x86-64-psABI-r252.pdf para obtener una copia de la versión actual de la especificación. Consulte también la wiki de etiquetas x86 para obtener enlaces a ABI (y muchas más cosas buenas).

Ver página 17 del abi PDF:

Clasificación El tamaño de cada argumento se redondea a ocho bytes. (nota al pie: por lo tanto, la pila siempre estará alineada en ocho bytes).

Además (pág. 16: Marco de pila ):

El final del área del argumento de entrada se alineará en un límite de 16 bytes (32, si se pasa __m256 en la pila). En otras palabras, el valor ( %rsp + 8 ) siempre es un múltiplo de 16 (32) cuando el control se transfiere al punto de entrada de la función.

Si lo hubieran diseñado de modo que diferentes tipos de enteros tuvieran diferentes anchos en la pila, pero los tipos de 8 bytes todavía estuvieran siempre alineados en 8 bytes, habría reglas complicadas sobre dónde va el relleno (y, por lo tanto, dónde encuentra su función la llamada). args) según los tipos de argumentos actuales y anteriores. Y significaría que funciones variadas como printf necesitarían una convención de llamada diferente que no incluyera los argumentos.


Las inserciones de 8 bits no se pueden codificar en absoluto. Solo están disponibles 16 bits (con un prefijo 0x66 ) o 64 bits (sin prefijo o REX.W=1 ). El manual de Intel es un poco confuso al respecto, lo que implica en el texto que push r32 r32 se puede codificar en modo de 64 bits (tal vez con REX.W = 0), pero ese no es el caso: vea cuántos bytes empuja la instrucción push en la pila cuando no especifico el tamaño del operando? .

over 4 years ago · Santiago Trujillo Denunciar

0

Al insertar valores en la pila, la inserción siempre debe basarse en el tamaño de palabra del sistema. Si eres un veterano como yo, son 16 bits (¡aunque tengo algunos sistemas de tamaño de palabra de 12 bits!), pero realmente depende del sistema.

Ya que está hablando de X86_64, estará hablando de palabras de 64 bits. Tengo entendido que el tamaño de la palabra generalmente está conectado a la cantidad mínima de bytes necesarios para abordar cualquier valor en la RAM del sistema. Dado que tiene un espacio de memoria de 64 bits, se requieren 64 bits (u 8 bytes, una "palabra cuádruple" basada en el tamaño de palabra original de 16 bits).

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda