Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

235
Views
¿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 answers
Answer question

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!