Programación Hibrida
Programación Hibrida
¿Qué es?
La programación hibrida es utilizada en los casos en donde el código en ensamblador
dificulta la estructuración del programa. La programación híbrida proporciona un
mecanismo por medio del cual podemos aprovechar las ventajas del lenguaje
ensamblador y los lenguajes de alto nivel, todo esto con el fin escribir programas más
rápidos y eficientes. La programación en lenguaje ensamblador proporciona un mayor
control sobre el hardware de la computadora, pero también dificulta la buena
estructuración de los programas.
Al trabajar con un lenguaje de alto nivel, en ocasiones nos encontramos con el problema
de que necesitamos que haga determinada función o trabajo, pero desafortunadamente
ésta solo existe en otro lenguaje que no es el que necesitamos utilizar, o simplemente, no
encontramos esa función en ningún lenguaje de alto nivel.
El comando rdtsc se utiliza para obtener el número de ciclos de reloj desde el inicio de la
CPU. El resultado es de 64 bits. La optimización de la compilación puede ser rápida y
fuerte, pero debe usarse con precaución.
Rust
Lenguaje de programación compilado, de propósito general y multiparadigma que está
siendo desarrollado por Fundación Rust. Es un lenguaje de programación
multiparadigmático que soporta programación funcional pura, por procedimientos,
imperativa y orientada a objetos.
Para manipulaciones de muy bajo nivel y por razones de desempeño, uno podría desear
controlar la CPU de manera directa. Para esto Rust soporta el uso de ensamblador en linea
a través de la macro asm!. La sintaxis es parecida a la de GCC & Clang:
Ejemplos escritos en ensamblador x86/x86-64
asm!(plantilla ensamblador
: operandos de salida
: operandos de entrada
: clobbers
: opciones
); g
Cualquier uso de asm está protegido por puertas de feature (requiere #![feature(asm)] en
el crate) y por supuesto requiere de un bloque unsafe.
Los operandos de salida, operandos de entrada, clobbers y opciones son todos opcionales
pero debes agregar el numero correcto de : en caso de que desees saltarlos.
Los operandos de entrada y salida siguen el mismo formato, Las expresiones de
operandos de salida deben ser valores lvalue mutables, o valores aun no asignados, si se
desea usar operandos reales seria obligatorio colocar llaves { }, Algunas instrucciones
modifican registros los cuales de otra forma hubieran mantenido valores diferentes es
por ello que usamos las lista de clobbers para indicar al compilador a que no asuma que
ningún valor cargado en dichos registros se mantendrá valido.
# #![feature(asm)]
# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
# fn main() {
let resultado: i32;
unsafe {
asm!("mov eax, 2" : "={eax}"(resultado) : : : "intel")
}
println!("eax es actualmente {}", resultado);
# }
Conclusiones