El ensamblaje en línea de c obtiene una “discrepancia de tamaño de operando” cuando se usa cmpxchg

3 minutos de lectura

avatar de usuario
as66

Estoy tratando de usar cmpxchg con ensamblaje en línea a través de c. Este es mi código:

static inline int
cas(volatile void* addr, int expected, int newval) {
    int ret;
    asm volatile("movl %2 , %%eax\n\t"
                "lock; cmpxchg %0, %3\n\t"
                "pushfl\n\t"
                "popl %1\n\t"
                "and $0x0040, %1\n\t"
                : "+m" (*(int*)addr), "=r" (ret)
                : "r" (expected), "r" (newval)
                : "%eax"
                );
    return ret;
}

Esta es la primera vez que uso en línea y no estoy seguro de qué podría estar causando este problema. Probé “cmpxchgl” también, pero aún nada. También probé quitando el candado. Obtengo “discrepancia en el tamaño del operando”. Creo que tal vez tenga algo que ver con el casting que le hago a addr, pero no estoy seguro. Intento cambiar int por int, así que realmente no entiendo por qué habría una falta de coincidencia de tamaño. Esto está usando el estilo AT&T. Gracias

  • Tratar de usar asm en línea es casi siempre un mala idea. ¿Ha considerado usar intrínsecos o bibliotecas?

    –David Wohlferd

    13 abr 2018 a las 21:41

  • También puede consultar stackoverflow.com/a/37825052/2189500

    –David Wohlferd

    13 abr 2018 a las 21:48

  • Es una tarea escolar, así que tenemos que usarla.

    – Ace66

    13 abr 2018 a las 21:55

  • Gracias David por el enlace, lo revisaré.

    – Ace66

    13 abr 2018 a las 21:56

  • Sé que no puedes controlar qué tareas te da tu maestro, pero asm en línea parece un mal uso del tiempo del estudiante. No es portátil entre compiladores, no es portátil entre plataformas, es extremadamente difícil hacerlo bien, incluso cuando se “ejecuta”, es posible que aún tenga problemas oscuros que lo muerdan más tarde. También interfiere con las optimizaciones del compilador, sacrifica posibilidades de uso constante. Y cuando haya terminado, la única habilidad que ha adquirido es aprender cómo funciona esta encarnación particular de asm en línea, algo que debe esforzarse para evitar usar en el código de producción.

    –David Wohlferd

    13 de abril de 2018 a las 23:08

  • @DavidWohlferd: Eso es lo que _oversimplified es para en los nombres de las funciones 😛

    – Peter Cordes

    15 de abril de 2018 a las 7:17

  • AFAIK, no hay una opción GCC (o cualquier otro compilador x86) adecuada para decirle que compile de esa manera, o ninguna función integrada para hacer un cmpxchg no atómico (o uno que sea atómico solo wrt. Interrupciones/controladores de señales en el núcleo actual / hilo)

    – Peter Cordes

    7 feb a las 13:33

  • @PSkocik: no veo una forma obvia de hacer esa optimización para asm en línea. Tenga en cuenta que es aún más importante para las operaciones de ALU que no sean agregar/sub (neg/xadd), p.ej fetch_or necesita un bucle de reintento CAS si se necesita el resultado anterior. (A menos que el operando solo tenga un conjunto de bits, en cuyo caso podría btspero es probable que solo valga la pena buscarlo if(__builtin_constant_p(x)).

    – Peter Cordes

    9 de febrero a las 5:57


  • Una última pregunta, ahora más directamente relevante para su respuesta: mientras clang-trunk lo acepta, a los clangs más antiguos no parece gustarles la parte de sintaxis de inteligencia de la plantilla y se quejan con “uso desconocido de instrucción mnemotécnica sin un sufijo de tamaño” gcc.godbolt.org/z/jfTa11Td1. ¿Alguna idea de por qué y se puede hacer que funcione incluso allí?

    – PSkocik

    9 de febrero a las 16:52

  • @PSkocik: clang-trunk acepta Intel-syntax inline asm ahora? Eso es genial, tendrá que actualizar las partes de sonido de ¿Cómo configurar gcc para usar la sintaxis de Intel de forma permanente? – Nunca antes había encontrado ninguna forma de hacer que clang usara la sintaxis de Intel. Tenga en cuenta que el error de clang que está viendo con clang más antiguo está usando nombres de operandos de AT&T con el orden de operandos de sintaxis Intel de esa parte de la plantilla: cmpxchg (%rdi), %edx que tiene los operandos al revés.

    – Peter Cordes

    9 de febrero a las 16:55


¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad