OS不会继续进入下一部分

问题描述 投票:1回答:1

使用NASM进行编译后,修复了所有错误之后,该程序现在完成了第一部分,但是到达第二部分时,它什么也不做。我试图结合两个指南来创建一个。第二部分在显示时显示;“计算器代码从此处开始

我是这种汇编语言的新手,所以我不知道如何解决它。如果您可以提供帮助,将不胜感激。如果您可以将答案中的代码写出来,以使我更轻松,也将不胜感激:)

[bits 16]           ; tell assembler that working in real mode(16 bit mode)
[org 0x7c00]        ; organize from 0x7C00 memory location where BIOS will load us

start:              ; start label from where our code starts

    xor ax,ax           ; set ax register to 0
    mov ds,ax           ; set data segment(ds) to 0
    mov es,ax           ; set extra segment(es) to 0
    mov bx,0x8000

    mov ax,0x13         ;clears the screen
    int 0x10            ;call bios video interrupt

    mov ah,02           ;clear the screen with big font
    int 0x10            ;interrupt display

    ;set cursor to specific position on screen
    mov ah,0x02         ; set value for change to cursor position
    mov bh,0x00         ; page
    mov dh,0x06         ; y cordinate/row
    mov dl,0x09         ; x cordinate/col
    int 0x10

    mov si, start_os_intro              ; point start_os_intro string to source index
    call _print_DiffColor_String        ; call print different color string function

    ;set cursor to specific position on screen
    mov ah,0x02
    mov bh,0x00
    mov dh,0x10
    mov dl,0x06
    int 0x10

    mov si,press_key                    ; point press_key string to source index
    call _print_GreenColor_String       ; call print green color string function

    mov ax,0x00         ; get keyboard input
    int 0x16            ; interrupt for hold & read input

    ;/////////////////////////////////////////////////////////////
    ; load second sector into memory

    mov ah, 0x02                    ; load second stage to memory
    mov al, 1                       ; numbers of sectors to read into memory
    mov dl, 0x80                    ; sector read from fixed/usb disk
    mov ch, 0                       ; cylinder number
    mov dh, 0                       ; head number
    mov cl, 2                       ; sector number
    mov bx, _OS_Stage_2             ; load into es:bx segment :offset of buffer
    int 0x13                        ; disk I/O interrupt

    jmp _OS_Stage_2                 ; jump to second stage


    ;/////////////////////////////////////////////////////////////
    ; declaring string datas here
    start_os_intro db 'Welcome to My OS!',0
    press_key db '>>>> Press any key <<<<',0

    login_username db 'Username : ',0
    login_password db 'Password : ',0

    display_text db '! Welcome to my Operating System !', 0

    os_info db 10, 'My Operating System, 16-Bit, version=1.0.0',13,0

    press_key_2 db 10,'Press any key to go to graphics view',0

    window_text db 10,'Graphics in OS......', 0
    hello_world_text db 10,10, '    Hello World!',0
    login_label db '#] Login please....(ESC to skip login)', 0


    ;/////////////////////////////////////////////////////////////
    ; defining printing string functions here

    ;****** print string without color

print_string:
    mov ah, 0x0E            ; value to tell interrupt handler that take value from al & print it

.repeat_next_char:
    lodsb                ; get character from string
    cmp al, 0                    ; cmp al with end of string
    je .done_print               ; if char is zero, end of string
    int 0x10                     ; otherwise, print it
    jmp .repeat_next_char        ; jmp to .repeat_next_char if not 0

.done_print:
    ret                         ;return

;****** print string with different colors

_print_DiffColor_String:
        mov bl,1                ;color value
    mov ah, 0x0E

.repeat_next_char:
    lodsb
    cmp al, 0
    je .done_print
    add bl,6               ;increase color value by 6
    int 0x10
    jmp .repeat_next_char

.done_print:
    ret

;****** print string with green color

_print_GreenColor_String:
    mov bl,10
    mov ah, 0x0E

.repeat_next_char:
    lodsb
    cmp al, 0
    je .done_print
    int 0x10
    jmp .repeat_next_char

.done_print:
    ret

;****** print string with white color

_print_WhiteColor_String:
    mov bl,15
    mov ah, 0x0E

.repeat_next_char:
    lodsb
    cmp al, 0
    je .done_print
    int 0x10
    jmp .repeat_next_char

.done_print:
    ret

;****** print string with yellow color

_print_YellowColor_String:
    mov bl,14
    mov ah, 0x0E

.repeat_next_char:
    lodsb
    cmp al, 0
    je .done_print
    int 0x10
    jmp .repeat_next_char

.done_print:
    ret


    ;///////////////////////////////////////////
    ; boot loader magic number
    times ((0x200 - 2) - ($ - $$)) db 0x00     ;set 512 bytes for boot sector which are necessary
    dw 0xAA55                                  ; boot signature 0xAA & 0x55


;////////////////////////////////////////////////////////////////////////////////////////

_OS_Stage_2 :

    mov al,2                    ; set font to normal mode
    mov ah,0                    ; clear the screen
    int 0x10                    ; call video interrupt

    mov cx,0                    ; initialize counter(cx) to get input

    ;***** print login_label on screen
    ;set cursor to specific position on screen
    mov ah,0x02
    mov bh,0x00
    mov dh,0x00
    mov dl,0x00
    int 0x10

    mov si,login_label              ; point si to login_username
    call print_string               ; display it on screen

    ;****** read username

    ;set cursor to specific position on screen
    mov ah,0x02
    mov bh,0x00
    mov dh,0x02
    mov dl,0x00
    int 0x10

    mov si,login_username          ; point si to login_username
    call print_string              ; display it on screen

_getUsernameinput:

    mov ax,0x00             ; get keyboard input
    int 0x16                ; hold for input

    cmp ah,0x1C             ; compare input is enter(1C) or not
    je .exitinput           ; if enter then jump to exitinput

    cmp ah,0x01             ; compare input is escape(01) or not
    je _skipLogin           ; jump to _skipLogin

    mov ah,0x0E             ;display input char
    int 0x10

    inc cx                  ; increase counter
    cmp cx,5                ; compare counter reached to 5
    jbe _getUsernameinput   ; yes jump to _getUsernameinput
    jmp .inputdone          ; else jump to inputdone

.inputdone:
    mov cx,0                ; set counter to 0
    jmp _getUsernameinput   ; jump to _getUsernameinput
    ret                     ; return

.exitinput:
    hlt


    ;****** read password

    ;set x y position to text
    mov ah,0x02
    mov bh,0x00
    mov dh,0x03
    mov dl,0x00
    int 0x10

    mov si,login_password               ; point si to login_username
    call print_string                   ; display it on screen

_getPasswordinput:

    mov ax,0x00
    int 0x16

    cmp ah,0x1C
    je .exitinput

    cmp ah,0x01
    je _skipLogin

    inc cx

    cmp cx,5
    jbe _getPasswordinput

    jmp .inputdone

.inputdone:
    mov cx,0
    jmp _getPasswordinput
    ret
.exitinput:
    hlt

;****** display display_text on screen

    ;set x y position to text
    mov ah,0x02
    mov bh,0x00
    mov dh,0x08
    mov dl,0x12
    int 0x10

    mov si, display_text        ;display display_text on screen
    call print_string

    ;set x y position to text
    mov ah,0x02
    mov bh,0x00
    mov dh,0x9
    mov dl,0x10
    int 0x10

    mov si, os_info     ;display os_info on screen
    call print_string

    ;set x y position to text
    mov ah,0x02
    mov bh,0x00
    mov dh,0x11
    mov dl,0x11
    int 0x10

    mov si, press_key_2     ;display press_key_2 on screen
    call print_string

    mov ah,0x00
    int 0x16


;//////////////////////////////////////////////////////////////////

_skipLogin:

    ;/////////////////////////////////////////////////////////////
    ; load third sector into memory

    mov ah, 0x03                    ; load third stage to memory
    mov al, 1
    mov dl, 0x80
    mov ch, 0
    mov dh, 0
    mov cl, 3                       ; sector number 3
    mov bx, _OS_Stage_3
    int 0x13

    jmp _OS_Stage_3

;////////////////////////////////////////////////////////////////////////////////////////

_OS_Stage_3:

    mov ax,0x13              ; clears the screen
    int 0x10

;CALCULATOR CODE STARTS HERE

  ;******************************************
  ; jumping from rel mode to protected mode
  ; by using disk interrupt

  mov ah, 0x02        ; load second stage to memory
  mov al, 0x10        ; numbers of sectors to read into memory
  mov dl, 0x80        ; sector read from fixed/usb disk
  mov ch, 0           ; cylinder number
  mov dh, 0           ; head number
  mov cl, 2           ; sector number
  mov bx, _start      ; load into es:bx segment :offset of buffer
  int 0x13            ; disk I/O interrupt

  ; before jumping clearing all interrupts
  cli

  ; jump to protected mode
  jmp _start                 ; jump to second stage

  times 1024 - ($-$$) db 0x00     ;set 1024 bytes for boot sector which are necessary
  dw 0xAA55                          ; boot signature 0xAA & 0x55


; bootloader code end

;******************************************
; x86 code begin 

_start:

main :

  ;******************************************
  ; set base pointer to heap
  ; and stack pointer to stack for functions and variables
  mov ebp, __HEAP__
  mov esp, __STACK__

  ; clear the screen
  call clear_screen

  ; set cursor mosition
  mov dword[X], 25
  mov dword[Y], 0
  push dword[X]
  push dword[Y]
  call goto_xy
  add esp, 8

  ; print os message
  mov esi, os_msg
  call print_string

  call print_new_line

  call print_new_line

  ; display the calculator menu
  call display_menu

;*************************************************
; this loop continue until valid coice is selected
.read_loop:

  ; read choice
  call read_single_key

  ; assign choice to choice variable
  mov ah, byte[KEYCODE]
  mov byte[choice], ah

  ; if other entry is entered continue to loop
  call read_single_key

  mov ah, byte[KEYCODE]
  cmp ah, byte[DELETE_KEY]
  je main

  ; if enter key is pressed jump to perform_calulation
  mov ah, byte[KEYCODE]
  cmp ah, byte[ENTER_KEY]
  je perform_operation

  jmp .read_loop

  ret

;******************************************
; this function displays calc string menu
display_menu :
  push ebp

  mov esi, calc_msg
  call print_string

  call print_new_line
  call print_new_line

  mov esi, menu_str
  call print_string  

  call print_new_line

  mov esi, addition_menu
  call print_string  

  call print_new_line

  mov esi, substraction_menu
  call print_string  

  call print_new_line

  mov esi, multiplication_menu
  call print_string  

  call print_new_line

  mov esi, division_menu
  call print_string  

  call print_new_line

  mov esi, modulus_menu
  call print_string  

  call print_new_line

  mov esi, logicaland_menu
  call print_string  

  call print_new_line

  mov esi, logicalor_menu
  call print_string  

  call print_new_line

  mov esi, clear_screen_menu
  call print_string  

  call print_new_line
  call print_new_line

  mov esi, select_choice_str
  call print_string  

  pop ebp
  ret

;***********************************************
; this function read bytes of data from keyboard
; by converting it into dword
perform_operation :

  ; if choice = clear screen(8)
  ; get choice
  mov al, byte[choice]
  cmp al, byte[KEYCODE_8]
  je perform_clear_screen

  call print_new_line

  ; read first number bytes
  mov esi, enter_first_number
  call print_string  

  call read_data

  ; check all read bytes are numerics in BUFFER
  lea ebx, [BUFFER]
  push ebx
  call check_all_bytes_are_numeric
  add esp, 4

  cmp eax, 0
  je .not_numerics

  ; convert bytes array into dword
  lea ebx, [BUFFER]
  push ebx
  call bytes_length
  add esp, 4

  push ebx
  push eax
  call byte_array_to_dword
  add esp, 8

  ; assign read dword to number_1
  mov dword[number_1], eax

  ; read second number
  call print_new_line

  mov esi, enter_second_number
  call print_string  

  call read_data

  ; check all read bytes are numerics in BUFFER
  lea ebx, [BUFFER]
  push ebx
  call check_all_bytes_are_numeric
  add esp, 4

  cmp eax, 0
  je .not_numerics

  ; convert bytes array into dword
  lea ebx, [BUFFER]
  push ebx
  call bytes_length
  add esp, 4

  push ebx
  push eax
  call byte_array_to_dword
  add esp, 8

  ; assign read dword to number_2
  mov dword[number_2], eax

  ; once reading numbers done, 
  ; jump to operation by choice function
  jmp perform_operation_by_choice

; when not numerics then display eror message
; and reload screen
.not_numerics :
  call print_new_line

  mov esi, error_msg
  call print_string

  call print_new_line

  call reload_screen

  ret

;****************************************************
; this function check the entered choice by keycodes,
; such as addition, substraction and jump to
; that specific procedure
perform_operation_by_choice :

  ; get choice
  mov al, byte[choice]

  ; if addition
  cmp al, byte[KEYCODE_1]
  je perform_addition

  ; if substraction
  cmp al, byte[KEYCODE_2]
  je perform_substraction

  ; if multiplication
  cmp al, byte[KEYCODE_3]
  je perform_multiplication

  ; if division
  cmp al, byte[KEYCODE_4]
  je perform_division

  ; if modulus
  cmp al, byte[KEYCODE_5]
  je perform_modulus

  ; if logical and
  cmp al, byte[KEYCODE_6]
  je perform_logical_and

  ; if logical or
  cmp al, byte[KEYCODE_7]
  je perform_logical_or

  ; if other
  ; then display invalid choice message
  call print_new_line
  mov esi, invalid_choice_str
  call print_string

  call reload_screen

  ret

;****************************
; call clear screen 
; and then reload screen
; to reload calc menu
perform_clear_screen :
  call clear_screen

  call reload_screen

  ret

;******************************************
; this function jumps to main
reload_screen :

  call print_new_line

  mov esi, reload_screen_msg
  call print_string

  call read_single_key

  jmp main

;******************************************
; this function gets two numbers add them
; and stores the result in result variable
perform_addition :

  mov eax, dword[number_1]
  mov ebx, dword[number_2]

  add eax, ebx
  mov dword[result], eax

  call print_new_line

  mov esi, addition
  call print_string

  ; convert dword to byte array
  lea ebx, [BUFFER]
  push dword[result]
  push ebx
  call dword_to_byte_array
  add esp, 8

  ; print byte array
  lea ebx, [BUFFER]
  push ebx
  call print_byte_array
  add esp, 4

  call print_new_line

  call reload_screen

  ret

;**********************************************
; this function gets two numbers substract them
; and stores the result in result variable
perform_substraction :

  mov eax, dword[number_1]
  mov ebx, dword[number_2]

  sub eax, ebx
  mov dword[result], eax

  call print_new_line

  mov esi, substraction
  call print_string

  ; convert dword to byte array
  lea ebx, [BUFFER]
  push dword[result]
  push ebx
  call dword_to_byte_array
  add esp, 8

  ; print byte array
  lea ebx, [BUFFER]
  push ebx
  call print_byte_array
  add esp, 4

  call print_new_line

  call reload_screen

  ret

;**********************************************
; this function gets two numbers multiply them
; and stores the result in result variable
; when performing multiplication
; if result goes out of dword boundry
; it saves in edx register
perform_multiplication :

  xor edx, edx
  mov eax, dword[number_1]
  mov ebx, dword[number_2]

  mul ebx
  mov dword[result], eax

  ; print result
  call print_new_line

  mov esi, multiplication
  call print_string

  ; print result
  lea ebx, [BUFFER]
  push dword[result]
  push ebx
  call dword_to_byte_array
  add esp, 8

  lea ebx, [BUFFER]
  push ebx
  call print_byte_array
  add esp, 4

  call print_new_line

  call reload_screen

  ret

;********************************************
; this function gets two numbers divide them
; and stores the result in result variable
perform_division :

  xor edx, edx
  mov eax, dword[number_1]
  mov ebx, dword[number_2]

  div ebx
  mov dword[result], eax

  ; print result
  call print_new_line

  mov esi, division
  call print_string

  lea ebx, [BUFFER]
  push dword[result]
  push ebx
  call dword_to_byte_array
  add esp, 8

  lea ebx, [BUFFER]
  push ebx
  call print_byte_array
  add esp, 4

  call print_new_line

  call reload_screen

  ret

;**********************************************
; this function gets two numbers take mod of it
; and stores the result in result variable
perform_modulus :

  xor edx, edx
  mov eax, dword[number_1]
  mov ebx, dword[number_2]

  div ebx
  mov dword[result], edx

  ; print result
  call print_new_line

  mov esi, modulus
  call print_string

  lea ebx, [BUFFER]
  push dword[result]
  push ebx
  call dword_to_byte_array
  add esp, 8

  lea ebx, [BUFFER]
  push ebx
  call print_byte_array
  add esp, 4

  call print_new_line

  call reload_screen

  ret

;***********************************
; this function and the two numbers
perform_logical_and :

  xor edx, edx
  mov eax, dword[number_1]
  mov ebx, dword[number_2]

  and eax, ebx
  mov dword[result], eax

  ; print result
  call print_new_line

  mov esi, logicaland
  call print_string

  lea ebx, [BUFFER]
  push dword[result]
  push ebx
  call dword_to_byte_array
  add esp, 8

  lea ebx, [BUFFER]
  push ebx
  call print_byte_array
  add esp, 4

  call print_new_line

  call reload_screen

  ret
;***********************************
; this function or the two numbers
perform_logical_or :

  xor edx, edx
  mov eax, dword[number_1]
  mov ebx, dword[number_2]

  or eax, ebx
  mov dword[result], eax

  ; print result
  call print_new_line

  mov esi, logicalor
  call print_string

  lea ebx, [BUFFER]
  push dword[result]
  push ebx
  call dword_to_byte_array
  add esp, 8

  lea ebx, [BUFFER]
  push ebx
  call print_byte_array
  add esp, 4

  call print_new_line

  call reload_screen

  ret

;*****************************************
; this function reads a single key
; stores character to KEYCHAR variable
; and keycode to KEYCODE variable
read_single_key :
  push ebp

  ; keyboard interrupt
    mov ax,0x00
    int 0x16

  mov byte[KEYCHAR], al
  mov byte[KEYCODE], ah

  ; display the entered character
    mov ah,0x0E
    int 0x10

  pop ebp
  ret

;**********************************************
; this function keep reading data until
; enter key is pressed
; it stores char data into global buffer BUFFER
read_data :
  push ebp

  mov ecx, 0

.input_keys_loop :

  ; keyboard interrupt
    mov ax,0x00
    int 0x16

  ; if enter key, jump to exit
    cmp ah, byte[ENTER_KEY]
    je .exitinput

  ; display entered character
    mov ah,0x0E
    int 0x10

  ; add it to buffer
  mov byte[BUFFER + ecx], al

  inc ecx

  jmp .input_keys_loop 

.exitinput:

  ; add null terminator in buffer  
  mov byte[BUFFER + ecx], 0x00

  pop ebp
    ret


;*********************************************
; this function removes everything from screen
; and set cursor location to (0,0)
clear_screen :
  mov ax,0x13
  mov al,2
    mov ah,0
    int 0x10

  mov byte[NEWLINE], 0

  ret


;******************************************

.next_char_loop :
  ; get character in al
    lodsb

    cmp al, 0
    je .exit

  int 0x10

  jmp .next_char_loop

.exit:
    ret

;******************************************
; this function print array of bytes
; param ebp - 8 = address of buffer
print_byte_array:

  mov ecx, 0
  mov ebx, dword[ebp - 8]

.loop:
  cmp byte[ebx + ecx], 0
  je .exit
  ; get byte from buffer
  mov al, byte[ebx + ecx]
  mov ah, 0x0E
  int 0x10

  inc ecx

  jmp .loop

.exit:
  ret

;******************************************
; this function prints a single character
; param ebp - 8 = chracter
print_char :
  push ebp

  xor eax, eax
  mov eax, dword[ebp - 8]

  mov ah, 0x0E
  int 0x10

  pop ebp
  ret

;***************************************************
; this function checks all bytes are from range 0..9
check_all_bytes_are_numeric : 
  push ebp

  ; get BUFFER address
  mov ebx, dword[ebp - 8]
  mov ecx, 0

.check_loop :
  cmp byte[ebx + ecx], 0
  je .exit

  ; if data is '0'
  cmp byte[ebx + ecx], 0x30
  jge .in_numeric

  mov eax, 0

  inc ecx

  jmp .check_loop

.in_numeric :

  ; if data is '9'
  cmp byte[ebx + ecx], 0x39
  jle .numeric

  mov eax, 0

  jmp .exit

.numeric :
  mov eax, 1
  inc ecx
  jmp .check_loop

.exit :
  pop ebp
  ret

;***************************************************
; this function gets each byte and multiply with 
; decimal position such as 1,10,100,1000,...
; and finally add with the result to get dword 
byte_array_to_dword : 
  push ebp

  ; get BUFFER address
  mov ebx, dword[ebp - 8]

  mov dword[number], 0
  mov dword[decimal_pos], 1

  ; get digit count
  mov ecx, dword[ebp - 12]
  dec ecx

.convert_dword_loop :
  cmp ecx, 0
  jl .exit

  xor eax, eax
  xor edx, edx
  ; get original data
  ; character '1' = 0x31
  ; substract 0x30 from it  
  mov al, byte[ebx + ecx]
  sub al, 0x30

  push ebx

  ; clear ebx and edx for multiplication
  xor ebx, ebx
  xor edx, edx

  ; num * 1,10,100...
  mov ebx, dword[decimal_pos]
  mul ebx

  add eax, dword[number]
  mov dword[number], eax

  ; clear ebx and edx for multiplication
  xor ebx, ebx
  xor edx, edx
  xor eax, eax

  mov eax, dword[decimal_pos]
  mov ebx, 10
  mul ebx
  mov dword[decimal_pos], eax

  pop ebx

  dec ecx

  jmp .convert_dword_loop

.exit :
  mov eax, dword[number]
  pop ebp
  ret

;****************************
; returns the number of bytes
bytes_length : 
  push ebp

  ; get buffer address
  mov ebx, dword[ebp - 8]
  mov eax, 0

.len_loop :
  cmp byte[ebx + eax], 0
  je .exit

  ; increment counter
  inc eax

  jmp .len_loop

.exit :
  pop ebp
  ret


;***************************************************
; ebp - 8 = passed number
; esp - 12 = count variable for storing the digit count
; eax = return of the count to caller
get_digit_count : 

  push ebp

  ; check if num is 0
  cmp dword[ebp - 8], 0
  je .num_is_zero

  ; allocate count variable on stack
  sub esp, 4
  mov dword[esp - 12], 0 ; count variable (count  = 0)

.dg_cnt_loop : 

  ; if num <= 0
  cmp dword[ebp - 8], 0
  jle .exit

  ; increment count 
  inc dword[esp - 12]

  ; clear eax, ebx and edx for division
  xor eax, eax
  xor ebx, ebx
  xor edx, edx

  ; num / 10
  mov eax, dword[ebp - 8]
  mov ebx, 10
  idiv ebx

  ; assign division result to num
  mov dword[ebp - 8], eax

  jmp .dg_cnt_loop

.num_is_zero : 
  ; if num is 0 then return 1
  mov eax, 1
  ; restore ebp
  pop ebp
  ret

.exit :
  ; assign count to eax
  mov eax, dword[esp - 12]
  ; restore allocated local variables
  add esp, 4
  ; restore ebp
  pop ebp
  ret

;******************************************************
; convert dword to array of bytes
; this function is same as itoa() in our C kernel code
; ebp - 8 = number
; ebp - 12 = address of byte array
; esp - 16 = digit_count variable
; esp - 20 = index variable
dword_to_byte_array : 

  push ebp

  ; allocate digit_count variable
  sub esp, 4
  mov dword[esp - 16], 0

  ; allocate index variable
  sub esp, 4
  mov dword[esp - 20], 0

  ; store the num value to ebx for temporary
  ; sometimes calling a function may lost the original value
  ; push the value in the stack
  mov ebx, dword[ebp - 8]
  push ebx

  ; get digit count of num by calling get_digit_count
  mov eax, dword[ebp - 8]
  push eax
  call get_digit_count
  add esp, 4

  ; pop the original num value
  pop ebx
  ; assign it to variable
  mov dword[ebp - 8], ebx


  ; assign digit count to digit count variable
  mov dword[esp - 16], eax

  ; decrement digit count by 1 as index for byte array
  dec eax

  ; assign index as digit_count to index variable
  mov dword[esp - 20], eax

  ; if num <= 0
  cmp dword[ebp - 8], 0
  je .dwrd_to_bt_zero_num

  ; if num > 0
.convert_char_loop : 
  ; if num <= 0
  cmp dword[ebp - 8], 0
  jle .exit_convrt_char

  ; clear eax, ebx and edx for division
  xor eax, eax
  xor ebx, ebx
  xor edx, edx

  ; num / 10
  mov eax, dword[ebp - 8]
  mov ebx, 10
  idiv ebx

  ; assign division result to num
  mov dword[ebp - 8], eax

  ; convert digit to character
  add dl, 0x30  ; 0x30 = '0'

  ; assign converted character to array
  mov ebx, dword[ebp - 12]  ; ebx = array address
  mov ecx, dword[esp - 20]  ; eax = index
  mov byte[ebx + ecx], dl   ; array[index] = char

  ; decrement index
  dec dword[esp - 20]

  jmp .convert_char_loop

.dwrd_to_bt_zero_num : 
  ; if digit count == 1
  cmp dword[esp - 16], 1
  je .digit_count_is_1

.digit_count_is_1 : 
  ; get array address
  mov ebx, dword[ebp - 12]
  mov byte[ebx], 0x30 ; character '0'
  mov byte[ebx + 1], 0x00 ; null terminator
  jmp .exit

.exit_convrt_char : 
  ; get array address
  mov ebx, dword[ebp - 12]
  mov eax, dword[esp - 16]
  mov byte[ebx + eax], 0x00 ; null terminator
  jmp .exit

.exit :

  add esp, 8

  pop ebp
  ret

;*****************************************
; this function increase NEWLINE variable
; and set cursor position to it
print_new_line :
  push ebp

  inc byte[NEWLINE]

  mov ah, 0x02
  mov bh, 0x00
  mov dl, 0; x pos
  mov dh, byte[NEWLINE]
  int 0x10

  pop ebp
  ret


;********************************************
; this function sets the cursor position to 
; provided x,y coordinates
goto_xy : 
  push ebp

  mov ah, 0x02
    mov bh, 0x00
  mov dl, byte[ebp - 8]; x pos
    mov dh, byte[ebp - 12] ; y pos
    int 0x10

  pop ebp

  ret

;********************************
; clear the gloabl buffer BUFFER
clear_global_buffer :
  mov ecx, 0

.clr_buf_loop :
  cmp ecx, dword[BUFSIZE]
  je .exit

  mov byte[BUFFER + ecx], 0x00

  jmp .clr_buf_loop

.exit :
  ret


; x86 code end


;******************************************
; set the required disk space we need
  times (4096 - ($ - $$)) db 0x00


;******************************************
; data sections

;******************************************
; read only data section
section .rodata
  __STACK__ dd 0x00FFFFFF
  __HEAP__ dd 0x00008C24
  BUFSIZE dd 512

  ; key codes

  ENTER_KEY db 0x1C
  DELETE_KEY db 0x0E

  KEYCODE_1 db 0x02
  KEYCODE_2 db 0x03
  KEYCODE_3 db 0x04
  KEYCODE_4 db 0x05
  KEYCODE_5 db 0x06
  KEYCODE_6 db 0x07
  KEYCODE_7 db 0x08
  KEYCODE_8 db 0x09

;******************************************
; initialized data section
section .data
  number dd 0
  decimal_pos dd 0
  NEWLINE db 0

  X dd 0
  Y dd 0

  number_1 dd 0
  number_2 dd 0
  result   dd 0

  os_msg db '! 80x86 Operating System !', 0
  calc_msg db '[ x86 Calculator Program ]', 0
  menu_str db '!--- Menu ---!', 0
  addition_menu db '1] Addition', 0
  substraction_menu db '2] Substraction', 0
  multiplication_menu db '3] Multiplication', 0
  division_menu db '4] Division', 0
  modulus_menu db '5] Modulus', 0
  logicaland_menu db '6] Logical AND', 0
  logicalor_menu db '7] Logical OR', 0
  clear_screen_menu db '8] Clear Screen', 0
  select_choice_str db 'Enter your choice : ', 0
  invalid_choice_str db 'Invalid choice', 0
  error_msg db 'Error : Please enter only numerics', 0

  addition db 'Addition : ', 0
  substraction db 'Substraction : ', 0
  multiplication db 'Multiplication : ', 0
  division db 'Division : ', 0
  modulus db 'Modulus : ', 0
  logicaland db 'Logical AND : ', 0
  logicalor db 'Logical OR : ', 0

  enter_first_number db 'Enter first number : ', 0
  enter_second_number db 'Enter Second number : ', 0

  reload_screen_msg db 'Press any key to reload screen...', 0

;******************************************
; block started by symbol(bss) section
section .bss
  BUFFER resb 512
  choice resb 1
  KEYCODE resb 1
  KEYCHAR resb 1
;*******************************************
assembly nasm x86-16 bootloader
1个回答
0
投票

您通过“ ;; CALCULATOR CODE STARTS HERE”指示的代码从未加载到内存中。您错误地使用了错误的功能编号!

; load third sector into memory
mov ah, 0x03                    ; load third stage to memory

用于加载的BIOS功能编号为02h,而不是您所写的0x03。


即使上述内容得到纠正,后面的代码也会重新加载那些第二和第三扇区(总共16个)并跳转到它们。这将导致无尽循环 ...

mov ah, 0x02
mov al, 0x10
mov dl, 0x80
mov ch, 0              ;
mov dh, 0              ;
mov cl, 2              ; SAME AS BEFORE !!!!!!!!
mov bx, _start
int 0x13
cli
jmp _start
© www.soinside.com 2019 - 2024. All rights reserved.