Foro de elhacker.net

Programación => ASM => Mensaje iniciado por: class_OpenGL en 25 Agosto 2016, 03:07 am



Título: [NASM] (Duda) El registro DS no funciona como debería
Publicado por: class_OpenGL en 25 Agosto 2016, 03:07 am
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
  1. BITS 16
  2.  
  3. start:
  4. xor ax, ax                 ; Set data segment to where we're loaded
  5. mov ds, ax
  6.  
  7. mov ax, text_string
  8. add ax, 7C00h
  9. mov si, ax                 ; Put string position into SI
  10. call print_string          ; Call our string-printing routine
  11.  
  12. jmp $                      ; Jump here - infinite loop!
  13.  
  14.  
  15. text_string: db 'This is my cool new OS!', 0
  16.  
  17.  
  18. print_string:                      ; Routine: output string in SI to screen
  19. mov ah, 0Eh                ; int 10h 'print char' function
  20.  
  21. .repeat:
  22. lodsb                      ; Get character from string
  23. cmp al, 0
  24. je .done                   ; If char is zero, end of string
  25. int 10h                    ; Otherwise, print it
  26. jmp .repeat
  27.  
  28. .done:
  29. ret
  30.  
  31.  
  32. times 510-($-$$) db 0      ; Pad remainder of boot sector with 0s
  33. 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
  1. BITS 16
  2.  
  3. start:
  4. xor ax, ax                 ; Lo ponemos como 0
  5. mov ds, ax
  6.  
  7. mov ax, text_string        ; Calculo manualmente la dirección de la caedna
  8. add ax, 7C00h
  9. mov si, ax                 ; La guardo en SI
  10.  
  11.        ...

Código con el que no funciona:
Código
  1. BITS 16
  2.  
  3. start:
  4. mov ax 0x07C0          ; Lo ponemos como 0
  5. mov ds, ax
  6.  
  7. mov ax, text_string    ; El cálculo debería ser DS * 0x10 + SI, lo que es lo mismo que
  8.                               ; 0x07C0 * 0x10 + SI, lo que es lo mismo que 0x7C00 + SI, que
  9.                               ; a su vez es lo mismo que el cálculo manual antes expuesto
  10. mov si, ax             ; La guardo en SI
  11.  
  12.        ...

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
  1. mov ah, 0x00
  2. SAHF
  3. CLC
  4. CLD
  5. CLTS
  6. mov ax, 0x07C0
  7. mov ds, ax

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

Espero que me puedan ayudar :D


Título: Re: [NASM] (Duda) El registro DS no funciona como debería
Publicado por: Yuki en 30 Septiembre 2016, 08:40 am
Em, bastante interesante lo que estas haciendo, dejame ver si encontre el problema.

Código
  1. BITS 16
  2.  
  3. start:
  4. mov ax,0x07C0          ; Lo ponemos como 0
  5. mov ds, ax
  6.  
  7. mov ax, text_string    ; El cálculo debería ser DS * 0x10 + SI, lo que es lo mismo que
  8.                               ; 0x07C0 * 0x10 + SI, lo que es lo mismo que 0x7C00 + SI, que
  9.                               ; a su vez es lo mismo que el cálculo manual antes expuesto
  10. mov si, ax             ; La guardo en SI
  11.  

Deberia ser:

Código
  1. BITS 16
  2.  
  3. start:
  4. mov ax,0x7C00          ; AX = 31744 // 7C00h // &H7C00 // 0x7C00
  5. mov ds, ax
  6.  
  7. add ax, text_string    ; utilizamos ADD para sumar la dirección con el valor previo de AX.
  8. mov si, ax             ; Preservamos el valor en SI.
  9.  

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

Y creo que podes achicarlo un poquito mas:
Código
  1. BITS 16
  2.  
  3. start:
  4. mov si,0x7C00          ; SI = 31744 // 7C00h // &H7C00 // 0x7C00
  5. add si, text_string
  6.        xor ds,ds
  7.  


Saludos!


Título: Re: [NASM] (Duda) El registro DS no funciona como debería
Publicado por: class_OpenGL en 1 Octubre 2016, 12:08 pm
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.