Pregunta

Me han pegado con esto durante semanas y no tienen idea de dónde voy mal porque NASM no me ha dado ningún error. El código es bastante explica por sí mismo debido a los comentarios.

este es el código que se carga desde la BIOS

 ;--------------------------------------------
 ; 'boot.asm'
 ; loaded from BIOS

 [org 0x7C00]
 [bits 16]

 ;--------------------------------------------

 main:
  mov ah, 0x0E  ; print function
  mov al, '.'   ; ascii char
  int 0x10   ; IO int

 resetdisk:
  mov ah, 0x00  ; reset function
  mov dl, 0x00  ; drive
  int 0x13   ; disk int
  jc resetdisk

 readdisk:
  mov bx, 0x8000  ; segment
  mov es, bx
  mov bx, 0x0000  ; offset

  mov ah, 0x02  ; read function
  mov al, 0x03  ; sectors
  mov ch, 0x00  ; cylinder
  mov cl, 0x02  ; sector
  mov dh, 0x00  ; head
  mov dl, 0x00  ; drive
  int 0x13   ; disk int
  jc readdisk
  jmp [es:bx]   ; buffer

 ;--------------------------------------------

 times 510 - ($ - $$) db 0x00
 db 0x55, 0xAA

Este es el código que debe ser (pero no es) cargado

 ;--------------------------------------------
 ; 'load.asm'
 ; loaded from 'boot.asm'

 [org 0x8000]
 [bits 16]

 ;--------------------------------------------

 main:
  mov ah, 0x0E  ; print function
  mov al, '.'   ; ascii char
  int 0x10   ; IO int

  jmp $    ; hang

Cualquier ayuda sería muy apreciada.

Patrick

¿Fue útil?

Solución

jmp [es:bx] no salta a la dirección de es:bx. Este comando hace un salto cerca de la dirección almacenada en la palabra de es:bx. Esta es la razón por un montón de montadores de más edad hacen se escribe este tipo de instrucción como jmp word ptr [es:bx] o incluso jmp near ptr [es:bx]; es más claro de esta manera lo que va a ocurrir. Lo que probablemente quiere aquí es un salto muy lejos a un lugar fijo:

; jmp far 8000:0000
db 0eah
dw 00000h ; offset
dw 08000h ; segment

Si desea saltar es:bx, utilice retf:

push es
push bx
retf

Otros consejos

No estoy seguro de lo que está tratando de lograr con el código, pero si he entendido bien, que desea leer unos pocos sectores del disco en la ubicación 0x8000 y luego ejecutar ese código?

Si ese es el caso, entonces usted tendrá que hacer explicitamente una llamada / JUMP para ese lugar en particular. El BIOS no llamar a ese código para usted. En el arranque, una vez que se ha inicializado el BIOS, que fijará el IP Instrucción Puntero a la dirección de 0x7C00. La CPU continuación, se iniciará a ejecutar el código secuencial, por lo que sin JMP / CALL para 0x8000 no lo puedo ejecutar el código en 0x8000 hasta que se haya ejecutado todas las direcciones de la memoria entre medio 0x7C00 a 0x8000, etc.

Así que la solución sería tener un JMP o llame a la instrucción después de su readdisk jc.

Si mi entendimiento es incorrecta, me disculpo. Espero que esto ayude.

Uno de gotcha con INT13 es que la cabeza y los números de pista comienzan en 0, pero los números del sector, por alguna razón comienzan en 1. Es posible comprobar que su utilidad sector de la escritura se ajusta a este esquema de numeración.

Preguntas:

  • ¿Cuántos puntos es lo que ves cuando arranque?
  • ¿El golpe de motor en disquete?

No sé si está utilizando un disquete para arrancar el sistema operativo, pero si usted está usando, le sugiero que usted declare algunas cosas después de la ORG y la declaración Bits, echar un vistazo (que son muy importantes):

JMP short main   ; Jump past disk description section
NOP              ; Pad out before disk description

; ------------------------------------------------------------------
; Disk description table, to make it a valid floppy
; Note: some of these values are hard-coded in the source!
; Values are those used by IBM for 1.44 MB, 3.5 diskette

OEMLabel            db "BERL OS"    ; Disk label - 8 chars
BytesPerSector      dw 512          ; Bytes per sector
SectorsPerCluster   db 1            ; Sectors per cluster
ReservedForBoot     dw 1            ; Reserved sectors for boot record
NumberOfFats        db 2            ; Number of copies of the FAT
RootDirEntries      dw 224          ; Number of entries in root dir
LogicalSectors      dw 2880         ; Number of logical sectors
MediumByte          db 0F0h         ; Medium descriptor byte
SectorsPerFat       dw 9            ; Sectors per FAT
SectorsPerTrack     dw 18           ; Sectors per track (36/cylinder)
Sides               dw 2            ; Number of sides/heads
HiddenSectors       dd 0            ; Number of hidden sectors
LargeSectors        dd 0            ; Number of LBA sectors
DriveNo             dw 0            ; Drive No: 0
Signature           db 41           ; Drive signature: 41 for floppy
VolumeID            dd 00000000h    ; Volume ID: any number
VolumeLabel         db "BERL OS"    ; Volume Label: any 11 chars
FileSystem          db "FAT12"      ; File system type: don't change!

; End of the disk description table
; ------------------------------------------------------------------

Es una buena idea poner esto.

Saludos.

No estoy seguro de por qué el código no funciona, ya que no puedo comprobar el todo el entorno (disco, volcado de memoria, etc) ... pero lo que puedo decir es ... el código es incorrecto . Que está cargando el segundo programa, no en 0x8000 (que era el punto de utilizar 0rg 0x8000 ¿verdad?), Pero al 0x80000.

La razón es que se utiliza el segmento: desplazamiento de direccionamiento en el camino equivocado, 0x8000:0x0000 la dirección que se resuelva a la dirección de 0x80000 lineal, ya el valor del segmento se desplaza a la izquierda por 4 bits una después se añadió a la compensación.

Para resolver este problema, debería echar un vistazo a un volcado de memoria y ver si el programa funciona como se espera que también .... eso o va a cargar la sectores erróneos del disco.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top