[NASM] (Duda) El registro DS no funciona como debería

Iniciado por class_OpenGL, 25 Agosto 2016, 03:07 AM

0 Miembros y 1 Visitante están viendo este tema.

class_OpenGL

Hola, muy buenas. Estaba viendo cómo se hacía una unidad de arranque desde ensamblador (NASM), pero tengo problemas con el registro DS. Muestro este código para mostrar mi duda:

Código (asm) [Seleccionar]
BITS 16

start:
xor ax, ax                 ; Set data segment to where we're loaded
mov ds, ax

mov ax, text_string
add ax, 7C00h
mov si, ax                 ; Put string position into SI
call print_string          ; Call our string-printing routine

jmp $                      ; Jump here - infinite loop!


text_string: db 'This is my cool new OS!', 0


print_string:                      ; Routine: output string in SI to screen
mov ah, 0Eh                ; int 10h 'print char' function

.repeat:
lodsb                      ; Get character from string
cmp al, 0
je .done                   ; If char is zero, end of string
int 10h                    ; Otherwise, print it
jmp .repeat

.done:
ret


times 510-($-$$) db 0      ; Pad remainder of boot sector with 0s
dw 0xAA55


Es un código sencillito, pero funciona. El problema está en que si hago que el registro DS valga 0x07C0, el ordenador no arranca con esta unidad de arranque, pero si calculo manualmente la dirección de la cadena de texto y hago que DS valga 0, el ordenador si que arranca con esta unidad.

Código con el que funciona:
Código (asm) [Seleccionar]
BITS 16

start:
xor ax, ax                 ; Lo ponemos como 0
mov ds, ax

mov ax, text_string        ; Calculo manualmente la dirección de la caedna
add ax, 7C00h
mov si, ax                 ; La guardo en SI
       
       ...


Código con el que no funciona:
Código (asm) [Seleccionar]
BITS 16

start:
mov ax 0x07C0          ; Lo ponemos como 0
mov ds, ax

mov ax, text_string    ; El cálculo debería ser DS * 0x10 + SI, lo que es lo mismo que
                              ; 0x07C0 * 0x10 + SI, lo que es lo mismo que 0x7C00 + SI, que
                              ; a su vez es lo mismo que el cálculo manual antes expuesto
mov si, ax             ; La guardo en SI
       
       ...


O hay algo que se me escapa, o es muy extraño todo... Gracias de antemano!




Vale, me he dado cuenta de que xor limpia parte/todo el registro FLAGS

He obtenido el registro con LAHF. Antes de usar xor, LAHF retornaba, en binario, 01000110, y después de usar xor, LAHF retornaba 00000000. He intentado hacer lo siguiente, pero sigue sin funcionar:

Código (asm) [Seleccionar]
mov ah, 0x00
SAHF
CLC
CLD
CLTS
mov ax, 0x07C0
mov ds, ax


Pero con este código si que funciona (algo hace XOR de lo que no me doy cuenta...):
Código (asm) [Seleccionar]
xor ax, ax            ; Algo más tiene que hacer XOR, porque aun reemplazando el valor de ax, sin XOR no funciona
mov ax, 0x07C0        ; Aquí reemplazamos todo ax
mov ds, ax


Espero que me puedan ayudar :D

Programador aficionado. Me quiero centrar en programar videojuegos. La API que uso para crearlos es OpenGL

Yuki

Em, bastante interesante lo que estas haciendo, dejame ver si encontre el problema.

Código (asm) [Seleccionar]

BITS 16

start:
mov ax,0x07C0          ; Lo ponemos como 0
mov ds, ax

mov ax, text_string    ; El cálculo debería ser DS * 0x10 + SI, lo que es lo mismo que
                               ; 0x07C0 * 0x10 + SI, lo que es lo mismo que 0x7C00 + SI, que
                               ; a su vez es lo mismo que el cálculo manual antes expuesto
mov si, ax             ; La guardo en SI


Deberia ser:

Código (asm) [Seleccionar]
BITS 16

start:
mov ax,0x7C00          ; AX = 31744 // 7C00h // &H7C00 // 0x7C00
mov ds, ax

add ax, text_string    ; utilizamos ADD para sumar la dirección con el valor previo de AX.
mov si, ax             ; Preservamos el valor en SI.


Ví que cambiaste 7C00h por por 0x07C0, No son lo mismo!

Y creo que podes achicarlo un poquito mas:
Código (asm) [Seleccionar]
BITS 16

start:
mov si,0x7C00          ; SI = 31744 // 7C00h // &H7C00 // 0x7C00
add si, text_string
        xor ds,ds



Saludos!

class_OpenGL

Cambié 7C00h por 0x07C0 para el registro DS porque el cálculo que se realiza es el siguiente:

Dirección efectiva = 0x10 * DS + SI, es decir, 0x10 * 0x07C0 + SI, lo que sería 0x7C00 + SI.

Programador aficionado. Me quiero centrar en programar videojuegos. La API que uso para crearlos es OpenGL