Red de conocimientos sobre prescripción popular - Remedios caseros - ¿Cómo escribir la capa inferior del lenguaje C? ¿Qué está sucediendo?

¿Cómo escribir la capa inferior del lenguaje C? ¿Qué está sucediendo?

El modelo de memoria del lenguaje C corresponde básicamente al modelo de almacenamiento real de la computadora von Neumann actual. Esta es la razón principal por la que C/C es adecuado para el desarrollo de bajo nivel. Además, otra razón por la que el lenguaje C es adecuado para el desarrollo de bajo nivel es que el lenguaje C admite muchas operaciones de bajo nivel y proporciona muchas funciones de nivel relativamente bajo.

Las siguientes preguntas se analizan por separado.

Problema: Operación de turno

Al utilizar el operador de turno, hay dos cuestiones que se deben aclarar:

(1), en la operación de turno derecha, ¿Los bits vacíos deben llenarse con ceros o bits de signo?

(2) ¿Qué números se pueden desplazar?

Respuesta y análisis:

" gt>y"

Desplazamiento a la derecha: nombre de la variable>; número de desplazamiento gt

Desplazamiento hacia la izquierda : nombre de variable

Después del desplazamiento, los bits de un extremo se "exprimen" y los bits del otro extremo se rellenan con ceros. En lenguaje C, los cambios no son circulares.

(1) La respuesta a la primera pregunta es sencilla, pero depende de diferentes situaciones. Si el número desplazado no tiene signo, rellénelo con ceros. Si es un número con signo, entonces es posible completar 0 o el bit de signo. Si desea resolver el problema de llenar los bits vacíos en la operación de desplazamiento a la derecha, declare la variable como sin signo, de modo que los bits vacíos se establezcan en 0.

(2) La respuesta a la segunda pregunta también es muy simple: si se mueven n bits, entonces el número de bits a desplazar no puede ser menor que 0 y debe ser menor que n. De esta forma, no se eliminarán todos los datos en una sola operación.

Por ejemplo, si los datos enteros ocupan 32 bits y n son los datos enteros, entonces n < lt31 y n

Tenga en cuenta que incluso si los espacios llenan el bit de signo, el desplazamiento a la derecha del entero con signo Tampoco es equivalente a división. Para probar esto, podemos pensar que -1 > gt1 no puede ser 0.

Q: Estructura segmentada

Estructura RPR_ATD_TLV_Title

{

ULONG RES 1:6;

p>

Tipo ULONG: 10;

ULONG RES 1: 6;

Longitud ULONG:

}; La estructura de segmento de bits es una estructura especial que es más conveniente que los operadores bit a bit cuando se requiere acceso bit a bit a múltiples bits de un byte o palabra.

La forma general de definición de estructura de bits es:

Nombre de estructura de bits de estructura (

Nombre de variable de tipo de datos: constante entera;

Nombre de variable de tipo de datos: constante entera;

}Variable de estructura de bits

Entre ellos: la constante entera debe ser un número entero no negativo de 0 a 15, que indica el número de binarios. dígitos, es decir, cuántos dígitos hay

El nombre de la variable es opcional y se puede dejar sin nombre

Por ejemplo, la estructura de bits se define de la siguiente manera. >

Estructura {

Incon sin firmar: 8; /*incon ocupa 0~7***8 bits*/

Color tx sin firmar: 4 /*txcolor ocupa alto; byte 0~3 bits* **4 bits*/

Bgcolor sin firmar: 3; /*bgcolor ocupa 4~6 bytes altos ***3 bits*/

Parpadeo sin firmar: 1; /*el parpadeo ocupa el bit 7 del byte de orden superior*/

} El acceso de los miembros de la estructura ch

bits es el mismo que el acceso de los miembros de la estructura

Por ejemplo, acceder al miembro bgcolor en la estructura de bits anterior se puede escribir como:

ch.bgcolor

Los miembros de la estructura de bits se pueden usar con otros miembros de la estructura.

Acceso y configuración bit a bit, rescate conveniente

Por ejemplo:

Información de estructura {

nombre de char[8];

int edad

Dirección de la estructura;

Salario variable;

Estado sin firmar: 1;

Salario sin firmar: 1;

}Trabajador;'

La estructura del ejemplo anterior define información sobre un trabajador. Hay dos miembros de la estructura de bits, cada miembro de la estructura de bits tiene solo un bit, por lo que solo se necesita un byte pero se guardan dos piezas de información. El primer bit de este byte indica el estado del trabajador y el segundo bit indica si se han pagado los salarios. Se puede ver que el uso de estructuras de bits puede ahorrar espacio de almacenamiento.

Ten cuidado de no exceder el límite.

Problema: alineación de bytes

Durante el proceso de programación con VC, una vez llamé a la estructura definida en la DLL y descubrí que la estructura estaba desordenada y no podía obtener el valor correcto. ser leído en absoluto. Más tarde descubrí que esto se debía a que la DLL y el programa de llamada usaban diferentes opciones de alineación de bytes, así que me gustaría preguntar, ¿qué es la alineación de bytes?

Respuesta y análisis:

Acerca de la alineación de bytes:

1. Cuando diferentes estructuras usan diferentes definiciones de alineación de bytes, puede dificultar la interacción.

2. Al comunicarse entre CPU, se puede utilizar la alineación de bytes para garantizar la unicidad, como el protocolo de comunicación y la estructura de registro al escribir controladores.

Tres métodos de alineación:

1. Alineación natural: igual al tamaño del tipo de datos.

2. Especifique el método de alineación:

#pragma pack(8) //Especifique Alinear como 8

#pragma pack() //Restaurar a; Valor original

3. Modo de calibración real:

Alineación real = valor mínimo (alineación secuencial, alineación natural)

Para tipos de datos complejos (como estructuras, etc.): La alineación real es la alineación real máxima de sus miembros;

Alineación real = máxima (alineación real 1, 2, 3,...)

Relleno del compilador. reglas:

1, este miembro es un múltiplo entero del miembro Actual Align y se agrega relleno delante de él.

La alineación real del componente = el valor mínimo (alineación real de la estructura, alineación establecida)

2. La estructura es un múltiplo entero de la estructura de alineación real y la alineación real del componente. el relleno se agrega más tarde.

Análisis de ejemplo:

#pragma pack(8) //Especifica Alinear como 8.

Prueba de estructura 1

{

char ch 1;

Long lo 1

char ch2

} prueba 1;

#Pragma package()

Ahora

STest1 = alineación de 4, tamaño STest1 = 12 ( 4 * 3)

La disposición de test1 en la memoria es la siguiente (FF es relleno):

00 - - - 04 - - - 08 - - - 12 - - -

01 FF FF FF 01 01 01 01 01 FF FF FF

ch1 - lo1 - ch2

#pragma pack(2) //Especificar Alinear como 2.

Prueba de estructura 2

{

char ch3

prueba STest1;

} prueba2

#PragmaPack()

Ahora, prueba 1 = alineación = 2, prueba 2 alineación = 2, prueba 2 tamaño = 14 (7 * 2).

La prueba2 se organiza en memoria de la siguiente manera:

00 - - - 04 - - - 08 - - - 12 - - -

02 FF 01 FF FF 01 01 01 01 01 FF FF FF

ch3 ch1 - lo1 - ch2

Notas:

1. Por lo tanto, el compilador no puede optimizar para una plataforma específica. Si la eficiencia es importante, intenta no utilizar #pragma pack. Si es necesario, es mejor configurarlo sólo donde sea necesario.

2. Si necesita agregar un paquete, debe agregarlo al archivo de encabezado que define la estructura. No confíe en las opciones de la línea de comandos porque si muchas personas usan archivos de encabezado, no todos saben que deben empaquetarse. Esto es especialmente cierto cuando se desarrollan bibliotecas para otros. Si una función de biblioteca usa una estructura como parámetro, se producirá un error cuando la persona que llama y el desarrollador de la biblioteca usen paquetes diferentes, y este error será difícil de detectar.

3. Excepto por la estructura de cuatro bytes, el paquete se agrega a los archivos de encabezado proporcionados por VC y BC; de lo contrario, nuestros programas de Windows no se ejecutarán normalmente.

4. No incluya otros archivos de encabezado después de #pragma pack(n). Si se cambia el valor de alineación en un archivo de encabezado incluido, se producirán resultados inesperados.

5. No permita que varias personas definan una estructura de datos al mismo tiempo. Esto garantiza un valor de embalaje constante. Pregunta: Operadores bit a bit

El lenguaje C se diferencia de otros lenguajes de alto nivel en que admite totalmente operadores bit a bit. Esto es algo similar a las operaciones de bits en lenguaje ensamblador. Los operadores bit a bit en C# son los siguientes:

━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Funcionamiento del operador

———————————————————————————————

amp Bit lógico AND

Bit lógico O

Bit lógico exclusivo O

Inversión lógica de 10 bits

gt gt desplazamiento a la derecha

lt lt desplazamiento a la izquierda

━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Nota:

1. Las operaciones bit a bit detectan, configuran o desplazan bits reales en un byte o palabra. Solo funciona con variables de caracteres y enteros y sus variantes, no con otros tipos de datos.

2. El resultado de la operación relacional y la expresión de la operación lógica solo puede ser 1 o 0. El resultado de una operación de bit puede ser un valor distinto de 0 o 1. Tenga en cuenta la diferencia entre operadores bit a bit y operadores lógicos. Por ejemplo, si x = 7, entonces el valor de x&8 es verdadero (dos valores distintos de cero todavía están en fase distintos de cero), mientras que el valor de x&8 es 0.

3. Utilice; con amp; amp;, ~ y! La relación entre

Los operadores amp y ~ tratan sus operandos como una secuencia y los operan poco a poco. Por ejemplo: 10; 12 = 8. Esto se debe a que el operador "" trata 10 y 12 como descripciones binarias de 10 y 1100, por lo que solo cuando el mismo bit de los dos operandos es 1 al mismo tiempo, el bit correspondiente en el El resultado generado es 1. De la misma manera, 10 12 = 14 (110), mediante operación de complemento, ~ 10 = -11 (65438) lt; ¿qué es una secuencia de bits>: amp amp, y! Un operador trata su operando como "verdadero" o "falso", donde 0 representa "falso" y cualquier valor distinto de cero se considera "verdadero". Devuelven 1 para "verdadero" y 0 para "falso". Para los operadores ";amp" y "", no evalúan el operando derecho en absoluto si el valor del operando izquierdo puede determinar el valor de la expresión. Entonces, 10 es 0 porque 10 no es 0;10. es 1, porque ni 10 ni 12 son cero; 10 12 también es 1, porque 10 no es 0;

Y en la última expresión, 12 no se evalúa en absoluto, ni tampoco la expresión 10 f().