Solución:
La dirección física se calcula a partir de 2 partes. i) dirección de segmento. ii) dirección de desplazamiento. El CS (registro de segmento de código) se utiliza para direccionar el segmento de código de la memoria, es decir, una ubicación en la memoria donde se almacena el código. El IP (puntero de instrucción) contiene el desplazamiento dentro del segmento de código de la memoria. Por tanto, CS: IP se utiliza para señalar la ubicación (es decir, para calcular la dirección física) del código en la memoria.
Dado que el Instruction Pointer (IP) es de 16 bits, significa que solo puede tener 64k instrucciones (2 ^ 16), lo que no era mucho ni siquiera en los años 80. Entonces, para expandir el espacio de direcciones, tiene un segundo registro que se dirige a bloques de 64k. Podría considerar cs: ip juntos como un registro de 32 bits que luego es capaz de direccionar 2 ^ 32 bytes … es decir, 4G, que es lo que obtiene en un procesador que usa direcciones de 32 bits. El 8086 estaba usando 20 bits de direcciones, por lo que podía acceder a 1 M de memoria.
La instrucción que se ejecutará a continuación es aquella en la dirección de memoria igual a:
16 * CS + IP
Esto permite direccionar 20 bits de memoria, a pesar de que los registros tienen solo 16 bits de ancho (y también crea dos formas distintas de codificar la mayoría de las direcciones).
El efecto de CS es análogo al de los otros registros de segmento. P.ej, DS
incrementa los accesos a datos (que no especifican otro registro de segmento) por 16 * DS
.
CS
Las instrucciones que modifican CS son:
- ljmp (salto lejano)
- lcall (llamada lejana), que empuja ip y cs a la pila, y luego salta lejos
- lref (retorno lejano), que invierte la llamada lejana
- int, que lee IP / CS de la tabla de vectores de interrupción
- iret, que invierte un int
CS no me puede modificar por mov
como los otros registros de segmento. Intentando codificarlo con el identificador estándar para CS, lo que GNU GAS 2.24 hace sin quejarse si escribe:
mov %ax, %cs
conduce a una excepción de código no válido cuando se ejecuta.
Para observar el efecto de CS, intente agregar lo siguiente a un sector de arranque y ejecutarlo en QEMU como se explica aquí https://stackoverflow.com/a/32483545/895245
/* $1 is the new CS, $1f the new IP. */
ljmp $1, $after1
after1:
/* Skip 16 bytes to make up for the CS == 1. */
.skip 0x10
mov %cs, %ax
/* cs == 1 */
ljmp $2, $after2
after2:
.skip 0x20
mov %cs, %ax
/* cs == 2 */
IP
IP aumenta automáticamente cada vez que se ejecuta una instrucción por la longitud de la codificación de esa instrucción: ¡es por eso que el programa avanza!
La IP es modificada por las mismas instrucciones que modifican CS, y también por las versiones no lejanas de esas instrucciones (caso más común).
La propiedad intelectual no se puede observar directamente, por lo que es más difícil jugar con ella. Verifique esta pregunta para ver alternativas: Lectura del contador del programa directamente