将AX移入CL - 操作码和操作数的无效组合

时间:2014-12-29 17:14:55

标签: assembly cpu-registers bootloader

我正在尝试将存储在AX寄存器中的值移动到CL寄存器中。我也试图通过寄存器对(从移动到BX:DH,和CX:CH)来做到这一点。

这是我的代码。

;;;
;;; Stage 1 - Boot Loader
;;; 

BITS 16             ; Start in 16 bit real mode
ORG 0x7C00          ; Loaded by BIOS at 0x7C00

start:  jmp stage1      ; Jump to the stage 1 section

;;;
;;; Parameter Block
;;; 

SECTORS_TRACK   dw  18  ; Sectors per track
HEADS_CYLINDER  dw  2   ; Heads per cylinder

;;;
;;; Strings Block
;;;

stage1_message  db  'Stage 1 - 16 bit real mode', 13, 10, 0

;;;
;;; Print String Function
;;; Input:
;;; - si = Null terminated string
;;; Output:
;;; - None
;;; 

print:
    lodsb           ; Load next byte from string in SI to AL
    or al, al       ; Does AL equal 0?
    jz print_done       ; Yes, null terminator found, return
    mov ah, 0eh     ; No, print the character
    int 10h
    jmp print       ; Repeat until null terminator found
print_done:
    ret         ; We are done, return

;;;
;;; LBA to CHS Function
;;; - Sector 1 = LBA 0
;;; Input:
;;; - ax = LBA value
;;; Output:
;;; - ax = Sector
;;; - bx = Head
;;; - cx = Cylinder
;;; Credit:
;;; - http://www.osdever.net/tutorials/view/lba-to-chs
;;;

lbachs:
    push dx
    xor dx, dx
    mov bx, [SECTORS_TRACK]
    div bx
    inc dx
    push dx
    xor dx, dx
    mov bx, [HEADS_CYLINDER]
    div bx
    mov cx, ax
    mov bx, dx
    pop ax
    pop dx
    ret

;;;
;;; Load Stage 2 Function
;;;

stage2:
    mov ax, 0x01        ; LBA 1 = Sector 2
    call lbachs     ; Convert LBA to CHS

    mov ah, 0x02        ; Read disk sectors function
    mov al, 0x01        ; Read one sector only (512 bytes)
    mov dl, 0x00        ; Drive 0 (Floppy Disk 1)

    mov cl, ax      ; Sector - Stored in AX - ERROR
    mov dh, bx      ; Head - Stored in BX - ERROR
    mov ch, cx      ; Cylinder - Stored in CX - ERROR

    mov bx, 0x2000      ; Put loaded data into segment 0x2000:0x0000
    mov es, bx      ; Load segment into ES (Segment parameter)
    mov bx, 0x0000      ; Load segment offset into BX (Offset parameter)

    int 0x13        ; Call BIOS read disk sectors function
    jc stage2       ; Error occurred, try loading again

    jmp 0x2000:0x0000   ; Loading complete, jump to stage 2

;;;
;;; Stage 1 Section
;;;

stage1:
    mov si, stage1_message  ; Load the stage 1 message
    call print      ; Call the print function

    jmp stage2      ; Attempt to load stage 2

;;;
;;; Footer Information
;;;

times 510-($-$$) db 0       ; Fill remainder of bootloader with 0's
dw 0xAA55           ; Standard PC boot signature at the end

造成问题的三条线位于stage1:上方的底部附近,并标有ERROR

字样

如果有人能帮助我,我会非常感激。此外,如果您在我的代码中发现任何其他异常情况,请随时告诉我。我正在开发这个作为第一阶段的引导加载程序,进入二级内核。

提前感谢您的建议和考虑。

1 个答案:

答案 0 :(得分:4)

问题,正如您对原始问题的评论所述,是您试图将16位寄存器的内容移动到8位寄存器中。你不能这样做,因为寄存器的大小不同。

如果要将数据从AX寄存器移入CL寄存器,则必须决定是要低位(AL寄存器)还是高位(AH寄存器)。也就是说,你可以写:

mov cl,al   ; moves the low 8 bits of AX into CL

或者

mov cl,ah   ; moves the high 8 bits of AX into CL

但是你不能将所有16位AX放入CL的8位。

现在,考虑一下你的代码。你有:

call lbachs     ; Convert LBA to CHS

mov ah, 0x02        ; Read disk sectors function
mov al, 0x01        ; Read one sector only (512 bytes)
mov dl, 0x00        ; Drive 0 (Floppy Disk 1)

mov cl, ax      ; Sector - Stored in AX - ERROR
mov dh, bx      ; Head - Stored in BX - ERROR
mov ch, cx      ; Cylinder - Stored in CX - ERROR

由于您正在调用lbachs来获取AX,BX和CX寄存器中的某些信息,因此无法正常工作,但随后您立即踩踏AH和AL(两半的AX)。您需要更改操作顺序,以便不会覆盖内容。我想你想要的是:

call lbachs

mov ch, cl      ; Cylinder (returned in CX by lbachs)
mov cl, al      ; sector number (returned in AX by lbachs)
mov dh, bl      ; head (returned in BX by lbachs)
mov ah, 02      ; Read disk sectors function
mov al, 0x01    ; one sector
mov dl, 0x00    ; Drive 0

请注意,我在这里使用lbachs返回的值,然后覆盖返回这些值的寄存器。