2016-02-02 1 views
1

Ниже у меня есть код, который рисует 3 круга в 3 разных цветах .. это нормально .. но как добавить строку текста? Спасибо. Я сделал несколько тестов на виртуальных боксах (windows), но не повезло .. Любые идеи, чтобы это сработало.Загрузитель с текстом и графикой ... howto? (With nasm)

BITS 16 
 
ORG 100h 
 

 
push 0a000h   ;Video memory graphics segment 
 
pop es 
 

 
mov ax, 0013h   ;[email protected] 
 
int 10h 
 

 

 
push 0Eh    ;Blue 
 
push 10    ;cX 
 
push 10    ;cY 
 
push 10    ;Radius 
 
call drawFilledCircle 
 

 
push 02h    ;Blue 
 
push 40    ;cX 
 
push 40    ;cY 
 
push 30    ;Radius 
 
call drawFilledCircle 
 

 
push 06h    ;Blue 
 
push 140    ;cX 
 
push 100    ;cY 
 
push 70    ;Radius 
 
call drawFilledCircle 
 

 

 

 
;Wait for a key 
 
xor ah, ah 
 
int 16h 
 
loc db "KERNEL IMG" 
 

 
.LOOP: 
 
      push cx 
 
      mov  cx, 0x000B       ; eleven character name 
 
      mov  si, loc 
 
      ; image name to find 
 
      push di 
 
    rep cmpsb          ; test for entry match 
 
      pop  di 
 
      ;je  LOAD_FAT 
 
      pop  cx 
 
      add  di, 0x0020       ; queue next directory entry 
 
      loop .LOOP 
 
      ;jmp  FAILURE 
 
;Restore text mode 
 
mov ax, 0003h 
 
int 10h 
 

 
;Return 
 
mov ax, 4c00h 
 
int 21h 
 

 

 
;Color 
 
;cX 
 
;cY 
 
;R 
 
drawFilledCircle: 
 
push bp 
 
mov bp, sp 
 

 
sub sp, 02h 
 

 
mov cx, WORD [bp+04h] ;R 
 

 
mov ax, cx    
 
mul ax     ;AX = R^2 
 
mov WORD [bp-02h], ax ;[bp-02h] = R^2 
 

 

 

 
mov ax, WORD [bp+06h] 
 
sub ax, cx    ;i = cY-R 
 
mov bx, WORD [bp+08h] 
 
sub bx, cx    ;j = cX-R 
 

 
shl cx, 1 
 
mov dx, cx    ;DX = Copy of 2R 
 

 
.advance_v: 
 
push cx 
 
push bx 
 

 
mov cx, dx 
 

 
.advance_h: 
 
    ;Save values 
 
    push bx 
 
    push ax 
 
    push dx 
 

 
    ;Compute (i-y) and (j-x) 
 
    sub ax, WORD [bp+06h] 
 
    sub bx, WORD [bp+08h] 
 

 
    mul ax     ;Compute (i-y)^2 
 

 
    push ax 
 
    mov ax, bx    
 
    mul ax 
 
    pop bx     ;Compute (j-x)^2 in ax, (i-y)^2 is in bx now 
 

 
    add ax, bx    ;(j-x)^2 + (i-y)^2 
 
    cmp ax, WORD [bp-02h] ;;(j-x)^2 + (i-y)^2 <= R^2 
 

 
    ;Restore values before jump 
 
    pop dx 
 
    pop ax 
 
    pop bx 
 

 
    ja .continue   ;Skip pixel if (j-x)^2 + (i-y)^2 > R^2 
 

 
    ;Write pixel 
 
    push WORD [bp+0ah] 
 
    push bx 
 
    push ax 
 
    call writePx 
 

 

 
.continue: 
 

 
    ;Advance j 
 
    inc bx 
 
loop .advance_h 
 

 
;Advance i 
 
inc ax 
 

 

 
pop bx   ;Restore j 
 
pop cx   ;Restore counter 
 

 
loop .advance_v 
 

 
add sp, 02h 
 

 

 
pop bp 
 
ret 08h 
 

 

 

 
;Color 
 
;X 
 
;Y 
 
writePx: 
 
push bp 
 
mov bp, sp 
 

 
push ax 
 
push bx 
 

 
mov bx, WORD [bp+04h] 
 
mov ax, bx 
 
shl bx, 6 
 
shl ax, 8 
 
add bx, ax  ;320 = 256 + 64 
 

 
add bx, WORD [bp+06h] 
 
mov ax, WORD [bp+08h] 
 

 
;TODO: Clip 
 

 
mov BYTE [es:bx], al 
 

 
pop bx 
 
pop ax 
 

 
pop bp 
 
ret 06h 
 

 

 

 

 

 
times 510-($-$$) db 0 \t ; Fill the rest with zeros 
 
dw 0xAA55 \t \t ; Boot loader signature

+1

Вы говорите, что это загрузчик (и у вас есть загрузчик подпись в конце), но я запутался по тому факту, что у вас есть 'ORG 100h'. Эта организация была бы нормальной для программы DOS COM. –

+1

Обычно большинство загрузчиков используют 'ORG 0x7c00' или' ORG 0x0000', а затем устанавливают регистр _DS_ для запуска загрузчика. Если вы использовали 'ORG 0x0000', вам нужно установить _DS_ в 0x07c0, если вы используете' ORG 0x7c00', вы должны установить _DS_ в 0x0000. 0x07c0: 0000 и 0x0000: 0x7c00 оба сопоставляются с одним и тем же физическим адресом 0x07c00, где загрузчик загружается в память BIOS. –

+1

Вы разместили 'loc db 'KERNEL IMG' 'после' int 16h', поэтому он будет выполнен как код после завершения int 16h. Поместите переменные в свой код после последнего кода и перед сигнатурой загрузки, чтобы избежать этой проблемы. –

ответ

-1

BITS 16 
 

 
[ORG 0x7C00] 
 

 

 

 

 
;ORG 100h 
 

 
    
 

 
push 0a000h   ;Video memory graphics segment 
 
pop es 
 

 
mov ax, 0013h   ;[email protected] 
 
int 10h 
 

 

 
push 0Eh    ;Blue 
 
push 10    ;cX 
 
push 10    ;cY 
 
push 10   ;Radius 
 
call drawFilledCircle 
 

 
push 02h    ;Blue 
 
push 40    ;cX 
 
push 40    ;cY 
 
push 30   ;Radius 
 
call drawFilledCircle 
 

 
push 06h    ;Blue 
 
push 140    ;cX 
 
push 100    ;cY 
 
push 70   ;Radius 
 
call drawFilledCircle 
 

 

 

 

 
;Wait for a key 
 
;xor ah, ah 
 
;int 16h 
 

 
    
 

 

 
main: \t \t ; Label for the start of the main program 
 

 
mov ax,0x0000 \t ; Setup the Data Segment register 
 
\t \t ; Location of data is DS:Offset 
 
mov ds,ax \t ; This can not be loaded directly it has to be in two steps. 
 
\t \t ; 'mov ds, 0x0000' will NOT work due to limitations on the CPU 
 

 
mov si, HelloWorld \t ; Load the string into position for the procedure. 
 

 

 
call PutStr \t ; Call/start the procedure 
 

 

 

 

 

 

 
;jmp $ \t \t ; Never ending loop 
 

 
; Procedures 
 
PutStr: \t \t ; Procedure label/start 
 
; Set up the registers for the interrupt call 
 
mov ah,0x0E \t ; The function to display a chacter (teletype) 
 
mov bh,0x00 \t ; Page number 
 
mov bl,0x07 \t ; Normal text attribute 
 

 
.nextchar \t ; Internal label (needed to loop round for the next character) 
 
lodsb \t \t ; I think of this as LOaD String Block 
 
\t \t ; (Not sure if thats the real meaning though) 
 
\t \t ; Loads [SI] into AL and increases SI by one 
 
; Check for end of string '0' 
 
or al,al \t ; Sets the zero flag if al = 0 
 
\t \t ; (OR outputs 0's where there is a zero bit in the register) 
 
jz .return \t ; If the zero flag has been set go to the end of the procedure. 
 
\t \t ; Zero flag gets set when an instruction returns 0 as the answer. 
 
int 0x10 \t ; Run the BIOS video interrupt 
 
jmp .nextchar \t ; Loop back round tothe top 
 
.return \t \t ; Label at the end to jump to when complete 
 
; ret \t \t ; Return to main program 
 
;Wait for a key 
 
xor ah, ah 
 
int 16h 
 

 
push 01h    ;Blue 
 
push 100    ;cX 
 
push 90    ;cY 
 
push 140   ;Radius 
 
call drawFilledCircle 
 

 

 
;ret 
 
; Data 
 

 
HelloWorld db ' WELCOME !! Press Enter ',10,10,0 
 

 

 

 
loc db "KERNEL IMG" 
 

 
.LOOP: 
 
      push cx 
 
      mov  cx, 0x000B       ; eleven character name 
 
      mov  si, loc 
 
         ; image name to find 
 
      push di 
 
    rep cmpsb          ; test for entry match 
 
      pop  di 
 
      ;je  LOAD_FAT 
 
      pop  cx 
 
      add  di, 0x0020       ; queue next directory entry 
 
      loop .LOOP 
 
      ;jmp  FAILURE 
 

 

 

 

 

 
;Restore text mode 
 
mov ax, 0003h 
 
int 10h 
 

 
;Return 
 
mov ax, 4c00h 
 
int 21h 
 

 

 
;Color 
 
;cX 
 
;cY 
 
;R 
 
drawFilledCircle: 
 
push bp 
 
mov bp, sp 
 

 
sub sp, 02h 
 

 
mov cx, WORD [bp+04h] ;R 
 

 
mov ax, cx    
 
mul ax     ;AX = R^2 
 
mov WORD [bp-02h], ax ;[bp-02h] = R^2 
 

 

 

 
mov ax, WORD [bp+06h] 
 
sub ax, cx    ;i = cY-R 
 
mov bx, WORD [bp+08h] 
 
sub bx, cx    ;j = cX-R 
 

 
shl cx, 1 
 
mov dx, cx    ;DX = Copy of 2R 
 

 
.advance_v: 
 
push cx 
 
push bx 
 

 
mov cx, dx 
 

 
.advance_h: 
 
    ;Save values 
 
    push bx 
 
    push ax 
 
    push dx 
 

 
    ;Compute (i-y) and (j-x) 
 
    sub ax, WORD [bp+06h] 
 
    sub bx, WORD [bp+08h] 
 

 
    mul ax     ;Compute (i-y)^2 
 

 
    push ax 
 
    mov ax, bx    
 
    mul ax 
 
    pop bx     ;Compute (j-x)^2 in ax, (i-y)^2 is in bx now 
 

 
    add ax, bx    ;(j-x)^2 + (i-y)^2 
 
    cmp ax, WORD [bp-02h] ;;(j-x)^2 + (i-y)^2 <= R^2 
 

 
    ;Restore values before jump 
 
    pop dx 
 
    pop ax 
 
    pop bx 
 

 
    ja .continue   ;Skip pixel if (j-x)^2 + (i-y)^2 > R^2 
 

 
    ;Write pixel 
 
    push WORD [bp+0ah] 
 
    push bx 
 
    push ax 
 
    call writePx 
 

 

 
.continue: 
 

 
    ;Advance j 
 
    inc bx 
 
loop .advance_h 
 

 
;Advance i 
 
inc ax 
 

 

 
pop bx   ;Restore j 
 
pop cx   ;Restore counter 
 

 
loop .advance_v 
 

 
add sp, 02h 
 

 

 
pop bp 
 
ret 08h 
 

 

 

 
;Color 
 
;X 
 
;Y 
 
writePx: 
 
push bp 
 
mov bp, sp 
 

 
push ax 
 
push bx 
 

 
mov bx, WORD [bp+04h] 
 
mov ax, bx 
 
shl bx, 6 
 
shl ax, 8 
 
add bx, ax  ;320 = 256 + 64 
 

 
add bx, WORD [bp+06h] 
 
mov ax, WORD [bp+08h] 
 

 
;TODO: Clip 
 

 
mov BYTE [es:bx], al 
 

 
pop bx 
 
pop ax 
 

 
pop bp 
 
ret 06h 
 

 

 

 

 
times 510-($-$$) db 0 \t ; Fill the rest with zeros 
 
dw 0xAA55 \t \t ; Boot loader signature

1

но как я addmit текстовую строку?

Вы решили использовать видеорежим с разрешением 320x200 256 цветов в режиме 13h.
Для вывода текста вы можете использовать каждую функцию BIOS, которая имеет дело с текстовым выходом, так же, как и на экране текстового видео.

Этот видеорежим использует шрифт 8x8, поэтому вы можете позиционировать курсор в любой из ячеек со значением 40x25 = 1000 символов.

Пример написания красного цвета капитала B в центре экрана:

mov dx, 0C14h ;DH=12 row,    DL=20 column 
mov bh, 0  ;BH=0 display page 
mov ah, 02h ;AH=02h set cursor position function 
int 10h  ;video BIOS interrupt 

mov bx, 000Ch ;BH=0 display page,  BL=12 red 
mov ax, 0E42h ;AH=0Eh teletype function, AL=66 capital B 
int 10h  ;video BIOS interrupt 
Смежные вопросы