2012-05-08 13 views
8

No entiendo cómo se supone que funciona.¿Por qué el ensamblador en línea de GCC requiere información de trituración, pero MSVC no lo hace?

El ensamblador en línea de GCC es difícil de conseguir, pero muy específico sobre cómo marcar la información de trituración, para que el compilador sepa lo que está haciendo.

El Aserver en línea de Microsoft Visual C++ es realmente fácil de usar (siempre parece que solo funciona), pero no tengo idea de qué tipo de garantías o suposiciones hace sobre su código.

¿Trata VC++ de "autodetectar" qué registradores son destruidos? ¿Cómo sabe cómo se cambiarán los registros y el puntero de la pila? ¿Hace alguna suposición? Si es así, ¿cómo se solucionan esas suposiciones?

Respuesta

19

cuanto a por qué GCC no hacerlo de la manera MSVC hace, hay varias razones:

  1. GCC es un compilador retargettable, pero la sintaxis de montaje es sólo texto sin formato. Para que la detección de clobber sea automática, GCC tendría que analizar el lenguaje ensamblador para comprender qué registros están siendo eliminados (incluidos los implícitamente bloqueados por instrucciones cuyos códigos de operación no nombran un registro). Esto debería funcionar en todas las arquitecturas. Actualmente, GCC no analiza el lenguaje ensamblador; simplemente lo pega en la salida del conjunto, después de realizar las sustituciones %. La idea es generar y evitar el análisis sintáctico.

  2. En el lenguaje de ensamblado en línea de GCC, los registros de trincheras son la excepción más que la regla. La razón es que es un lenguaje más sofisticado que el de MSVC. El lenguaje ensamblador en línea de GCC asigna registros para usted. Por lo tanto, normalmente no utiliza algo como %eax directamente, sino más bien un código como %0 para el cual GCC sustituye un registro disponible. (¡Y para hacer eso, el compilador no tiene que entender el lenguaje ensamblador! Usted expresa las restricciones que aseguran que GCC sustituya un registro apropiado para %0 que se ajuste al uso) Solo necesita un troceador si su código ensamblador sobrescribe duro -registros codificados, no si está sobreescribiendo los operandos de salida asignados para usted por GCC.

Tenga en cuenta que con el montaje del CCG en línea, usted no tiene que escribir el código que carga sus operandos del lenguaje ensamblador de las expresiones C que producen sus valores iniciales, o que guarda sus operandos resultado en el C destinos.Por ejemplo, acaba de expresar que debe haber un operando de entrada de tipo "r" (registro) que se deriva de la expresión foo->bar + 1. GCC asigna el registro y genera el código para cargarlo desde foo->bar + 1, y luego reemplaza las ocurrencias de %0 en su plantilla de ensamblaje con el nombre de ese registro.

+2

+1, una respuesta muy sofisticada a la pregunta de seguimiento de OP :) –

+0

# 2 fue un comentario muy útil, ¡no tenía ni idea de eso! ¡Gracias! :) – Mehrdad

+0

en 1. arriba dice: * "La idea es generar y evitar el análisis" *, sin embargo, me parece que para el compilador recibir la información sobre los objetos cariados implica analizar de todos modos, ¿no? Partiendo de la impresión "posiblemente incorrecta" de que "el ensamblaje en línea podría no tener el objetivo de aumentar la independencia de la arquitectura, y será bastante fácil de ensamblar según la plataforma específica", sería estupendo que hubiera un diccionario para proporcionar la información eliminada del compilador. , en cambio, para permitir que los programadores olviden cosas. ¿Ha habido algún desarrollo desde que se hizo la pregunta en 2012? – humanityANDpeace

4

Presupuesto de the docs:

Al utilizar __asm ​​a escribir en lenguaje ensamblador en funciones de C/C++, que no es necesario para preservar el EAX, EBX, ECX, EDX, ESI, EDI o registros. Por ejemplo, en el ejemplo POWER2.C en Writing Functions with Inline Assembly, la función power2 no conserva el valor en el registro EAX. Sin embargo, el uso de estos registros afectará la calidad del código porque el asignador de registro no puede usarlos para almacenar valores en bloques __asm. Además, al usar EBX, ESI o EDI en el código ensamblador en línea, fuerza al compilador a guardar y restaurar esos registros en el prólogo y epílogo de la función.

Debe conservar otros registros que utilice (como DS, SS, SP, BP y registros de banderas) para el alcance del bloque __asm. Debe conservar los registros ESP y EBP a menos que tenga algún motivo para cambiarlos (para cambiar de pila, por ejemplo). También vea Optimizing Inline Assembly.

+0

1 sentirse tan tonto sin mirar a que en el docs ... – Mehrdad

+1

tipo de estallidos la pregunta, sin embargo: ¿por qué hacer esto no GCC? – Mehrdad

+2

Para resumir para nuestros otros lectores: "sí, MSVC detecta automáticamente qué registros son destruidos, mientras que GCC requiere que los marque explícitamente". – Crashworks

Cuestiones relacionadas