请求文件的 INFO 系统调用(如果存在)

System call for INFO for requested file (if it exists)

我正在尝试在 MikeOS 操作系统中设计和实现一个系统调用。该调用将通过 MikeOS 中的命令行界面 (CLI) 访问。我正在尝试进行系统调用 INFO,它将显示所请求文件(如果存在)的信息(未格式化)。显示的信息包括

我应该在其中添加信息系统调用。我不知道该怎么做或从哪里开始。我在 SERIAL 中添加但找不到任何关于调用 INFO 或如何这样做的好例子

源代码

; ==================================================================
; MikeOS -- The Mike Operating System kernel
; Copyright (C) 2006 - 2014 MikeOS Developers -- see doc/LICENSE.TXT
;
; COMMAND LINE INTERFACE
; ==================================================================




os_command_line:
    call os_clear_screen


    mov si, version_msg
    call os_print_string
    mov si, help_text
    call os_print_string




get_cmd:                ; Main processing loop
    mov di, input           ; Clear input buffer each time
    mov al, 0
    mov cx, 256
    rep stosb


    mov di, command         ; And single command buffer
    mov cx, 32
    rep stosb


    mov si, prompt          ; Main loop; prompt for input
    call os_print_string


    mov ax, input           ; Get command string from user
    call os_input_string


    call os_print_newline


    mov ax, input           ; Remove trailing spaces
    call os_string_chomp


    mov si, input           ; If just enter pressed, prompt again
    cmp byte [si], 0
    je get_cmd


    mov si, input           ; Separate out the individual command
    mov al, ' '
    call os_string_tokenize


    mov word [param_list], di   ; Store location of full parameters


    mov si, input           ; Store copy of command for later modifications
    mov di, command
    call os_string_copy






    ; First, let's check to see if it's an internal command...


    mov ax, input
    call os_string_uppercase


    mov si, input


    mov di, exit_string     ; 'EXIT' entered?
    call os_string_compare
    jc near exit


    mov di, help_string     ; 'HELP' entered?
    call os_string_compare
    jc near print_help


    mov di, cls_string      ; 'CLS' entered?
    call os_string_compare
    jc near clear_screen


    mov di, dir_string      ; 'DIR' entered?
    call os_string_compare
    jc near list_directory


    mov di, ver_string      ; 'VER' entered?
    call os_string_compare
    jc near print_ver


    mov di, time_string     ; 'TIME' entered?
    call os_string_compare
    jc near print_time


    mov di, date_string     ; 'DATE' entered?
    call os_string_compare
    jc near print_date


    mov di, cat_string      ; 'CAT' entered?
    call os_string_compare
    jc near cat_file


    mov di, del_string      ; 'DEL' entered?
    call os_string_compare
    jc near del_file


    mov di, copy_string     ; 'COPY' entered?
    call os_string_compare
    jc near copy_file


    mov di, ren_string      ; 'REN' entered?
    call os_string_compare
    jc near ren_file


    mov di, size_string     ; 'SIZE' entered?
    call os_string_compare
    jc near size_file


    mov di, serial_string       ; 'SERIAL' entered?
    call os_string_compare
    jc near serial_file




    ; If the user hasn't entered any of the above commands, then we
    ; need to check for an executable file -- .BIN or .BAS, and the
    ; user may not have provided the extension


    mov ax, command
    call os_string_uppercase
    call os_string_length




    ; If the user has entered, say, MEGACOOL.BIN, we want to find that .BIN
    ; bit, so we get the length of the command, go four characters back to
    ; the full stop, and start searching from there


    mov si, command
    add si, ax


    sub si, 4


    mov di, bin_extension       ; Is there a .BIN extension?
    call os_string_compare
    jc bin_file


    mov di, bas_extension       ; Or is there a .BAS extension?
    call os_string_compare
    jc bas_file


    jmp no_extension




bin_file:
    mov ax, command
    mov bx, 0
    mov cx, 32768
    call os_load_file
    jc total_fail


execute_bin:
    mov si, command
    mov di, kern_file_string
    mov cx, 6
    call os_string_strincmp
    jc no_kernel_allowed


    mov ax, 0           ; Clear all registers
    mov bx, 0
    mov cx, 0
    mov dx, 0
    mov word si, [param_list]
    mov di, 0


    call 32768          ; Call the external program


    jmp get_cmd         ; When program has finished, start again






bas_file:
    mov ax, command
    mov bx, 0
    mov cx, 32768
    call os_load_file
    jc total_fail


    mov ax, 32768
    mov word si, [param_list]
    call os_run_basic


    jmp get_cmd






no_extension:
    mov ax, command
    call os_string_length


    mov si, command
    add si, ax


    mov byte [si], '.'
    mov byte [si+1], 'B'
    mov byte [si+2], 'I'
    mov byte [si+3], 'N'
    mov byte [si+4], 0


    mov ax, command
    mov bx, 0
    mov cx, 32768
    call os_load_file
    jc try_bas_ext


    jmp execute_bin




try_bas_ext:
    mov ax, command
    call os_string_length


    mov si, command
    add si, ax
    sub si, 4


    mov byte [si], '.'
    mov byte [si+1], 'B'
    mov byte [si+2], 'A'
    mov byte [si+3], 'S'
    mov byte [si+4], 0


    jmp bas_file






total_fail:
    mov si, invalid_msg
    call os_print_string


    jmp get_cmd




no_kernel_allowed:
    mov si, kern_warn_msg
    call os_print_string


    jmp get_cmd




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


print_help:
    mov si, help_text
    call os_print_string
    jmp get_cmd




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


clear_screen:
    call os_clear_screen
    jmp get_cmd




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


print_time:
    mov bx, tmp_string
    call os_get_time_string
    mov si, bx
    call os_print_string
    call os_print_newline
    jmp get_cmd




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


print_date:
    mov bx, tmp_string
    call os_get_date_string
    mov si, bx
    call os_print_string
    call os_print_newline
    jmp get_cmd




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


print_ver:
    mov si, version_msg
    call os_print_string
    jmp get_cmd




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


kern_warning:
    mov si, kern_warn_msg
    call os_print_string
    jmp get_cmd




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


list_directory:
    mov cx, 0           ; Counter


    mov ax, dirlist         ; Get list of files on disk
    call os_get_file_list


    mov si, dirlist
    mov ah, 0Eh         ; BIOS teletype function


.repeat:
    lodsb               ; Start printing filenames
    cmp al, 0           ; Quit if end of string
    je .done


    cmp al, ','         ; If comma in list string, don't print it
    jne .nonewline
    pusha
    call os_print_newline       ; But print a newline instead
    popa
    jmp .repeat


.nonewline:
    int 10h
    jmp .repeat


.done:
    call os_print_newline
    jmp get_cmd




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


cat_file:
    mov word si, [param_list]
    call os_string_parse
    cmp ax, 0           ; Was a filename provided?
    jne .filename_provided


    mov si, nofilename_msg      ; If not, show error message
    call os_print_string
    jmp get_cmd


.filename_provided:
    call os_file_exists     ; Check if file exists
    jc .not_found


    mov cx, 32768           ; Load file into second 32K
    call os_load_file


    mov word [file_size], bx


    cmp bx, 0           ; Nothing in the file?
    je get_cmd


    mov si, 32768
    mov ah, 0Eh         ; int 10h teletype function
.loop:
    lodsb               ; Get byte from loaded file


    cmp al, 0Ah         ; Move to start of line if we get a newline char
    jne .not_newline


    call os_get_cursor_pos
    mov dl, 0
    call os_move_cursor


.not_newline:
    int 10h             ; Display it
    dec bx              ; Count down file size
    cmp bx, 0           ; End of file?
    jne .loop


    jmp get_cmd


.not_found:
    mov si, notfound_msg
    call os_print_string
    jmp get_cmd




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


del_file:
    mov word si, [param_list]
    call os_string_parse
    cmp ax, 0           ; Was a filename provided?
    jne .filename_provided


    mov si, nofilename_msg      ; If not, show error message
    call os_print_string
    jmp get_cmd


.filename_provided:
    call os_remove_file
    jc .failure


    mov si, .success_msg
    call os_print_string
    mov si, ax
    call os_print_string
    call os_print_newline
    jmp get_cmd


.failure:
    mov si, .failure_msg
    call os_print_string
    jmp get_cmd




    .success_msg    db 'Deleted file: ', 0
    .failure_msg    db 'Could not delete file - does not exist or write protected', 13, 10, 0




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


size_file:
    mov word si, [param_list]
    call os_string_parse
    cmp ax, 0           ; Was a filename provided?
    jne .filename_provided


    mov si, nofilename_msg      ; If not, show error message
    call os_print_string
    jmp get_cmd


.filename_provided:
    call os_get_file_size
    jc .failure


    mov si, .size_msg
    call os_print_string


    mov ax, bx
    call os_int_to_string
    mov si, ax
    call os_print_string
    call os_print_newline
    jmp get_cmd




.failure:
    mov si, notfound_msg
    call os_print_string
    jmp get_cmd




    .size_msg   db 'Size (in bytes) is: ', 0




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


copy_file:
    mov word si, [param_list]
    call os_string_parse
    mov word [.tmp], bx


    cmp bx, 0           ; Were two filenames provided?
    jne .filename_provided


    mov si, nofilename_msg      ; If not, show error message
    call os_print_string
    jmp get_cmd


.filename_provided:
    mov dx, ax          ; Store first filename temporarily
    mov ax, bx
    call os_file_exists
    jnc .already_exists


    mov ax, dx
    mov cx, 32768
    call os_load_file
    jc .load_fail


    mov cx, bx
    mov bx, 32768
    mov word ax, [.tmp]
    call os_write_file
    jc .write_fail


    mov si, .success_msg
    call os_print_string
    jmp get_cmd


.load_fail:
    mov si, notfound_msg
    call os_print_string
    jmp get_cmd


.write_fail:
    mov si, writefail_msg
    call os_print_string
    jmp get_cmd


.already_exists:
    mov si, exists_msg
    call os_print_string
    jmp get_cmd




    .tmp        dw 0
    .success_msg    db 'File copied successfully', 13, 10, 0




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


ren_file:
    mov word si, [param_list]
    call os_string_parse


    cmp bx, 0           ; Were two filenames provided?
    jne .filename_provided


    mov si, nofilename_msg      ; If not, show error message
    call os_print_string
    jmp get_cmd


.filename_provided:
    mov cx, ax          ; Store first filename temporarily
    mov ax, bx          ; Get destination
    call os_file_exists     ; Check to see if it exists
    jnc .already_exists


    mov ax, cx          ; Get first filename back
    call os_rename_file
    jc .failure


    mov si, .success_msg
    call os_print_string
    jmp get_cmd


.already_exists:
    mov si, exists_msg
    call os_print_string
    jmp get_cmd


.failure:
    mov si, .failure_msg
    call os_print_string
    jmp get_cmd




    .success_msg    db 'File renamed successfully', 13, 10, 0
    .failure_msg    db 'Operation failed - file not found or invalid filename', 13, 10, 0


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


serial_file: 


    mov ah, 2           ; Read disc sectors funtion 
    mov al, 1           ; numbers of sectors to read
    mov ch, 0           ; track/cylinder number 
    mov cl, 1           ; sector number 
    mov dh, 0           ; head number
    mov dl, 0           ; drive number (0=A, 80h = driv 0, 81h = drive 1)
    mov bx, disk_buffer     ; pointer to buffer
    int 13h             ; execute function; AH = status, AL = # of sectors read
    jc .serial_error        ; CF = 0 if successful; 1 is error


    mov si, .serial_msg
    call os_print_string


    mov ax, [disk_buffer + 29h] ; print the first 2 bytes of the serial number 
    call os_print_4hex


    mov si, .separator
    call os_print_string


    mov ax, [disk_buffer + 27h] ; print the second 2 bytes of serial number
    call os_print_4hex  


    call os_print_newline


    jmp .end


.serial_error:


    mov si, .error_msg
    call os_print_string


.end:
    jmp get_cmd


    .separator  db '_', 0
    .serial_msg db 'The serial number is: ', 0
    .error_msg  db 'Error reading disk.', 13, 10, 0
    .disk_buffer    times 512 db 0 






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


exit:
    ret




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


    input           times 256 db 0
    command         times 32 db 0


    dirlist         times 1024 db 0
    tmp_string      times 15 db 0


    file_size       dw 0
    param_list      dw 0


    bin_extension       db '.BIN', 0
    bas_extension       db '.BAS', 0


    prompt          db '> ', 0


    help_text       db 'Commands: DIR, COPY, REN, DEL, CAT, SIZE, CLS, HELP, TIME, DATE, VER, EXIT, SERIAL', 13, 10, 0
    invalid_msg     db 'No such command or program', 13, 10, 0
    nofilename_msg      db 'No filename or not enough filenames', 13, 10, 0
    notfound_msg        db 'File not found', 13, 10, 0
    writefail_msg       db 'Could not write file. Write protected or invalid filename?', 13, 10, 0
    exists_msg      db 'Target file already exists!', 13, 10, 0


    version_msg     db 'MikeOS ', MIKEOS_VER, 13, 10, 0


    exit_string     db 'EXIT', 0
    help_string     db 'HELP', 0
    cls_string      db 'CLS', 0
    dir_string      db 'DIR', 0
    time_string     db 'TIME', 0
    date_string     db 'DATE', 0
    ver_string      db 'VER', 0
    cat_string      db 'CAT', 0
    del_string      db 'DEL', 0
    ren_string      db 'REN', 0
    copy_string     db 'COPY', 0
    size_string     db 'SIZE', 0
    serial_string       db 'SERIAL', 0  
    kern_file_string    db 'KERNEL', 0
    kern_warn_msg       db 'Cannot execute kernel file!', 13, 10, 0




; ==================================================================

您可以通过查看 Mike 如何进行 os_get_file_size api 调用来轻松完成此操作。
对于您的任务,您不仅 return BX 中的 FileSize,而且您选择的任何其他寄存器中的其他信息。
这可能是那个选择:

AL = Attribute byte.
CX = Creation Time.
DX = Creation Date
SI = Last Access Date
DI = Last Write Time
BX = File size in bytes

; --------------------------------------------------------------------------
; os_get_file_size -- Get file size information for specified file
; IN: AX = filename; OUT: BX = file size in bytes (up to 64K)
; or carry set if file not found

os_get_file_size:
    pusha
    call os_string_uppercase
    call int_filename_convert
    clc
    push ax
    call disk_read_root_dir
    jc .failure
    pop ax
    mov di, disk_buffer
    call disk_get_root_entry
    jc .failure
    mov word bx, [di+28]        <<<<< FileSize
    mov word [.tmp], bx
    popa
    mov word bx, [.tmp]
    ret
.failure:
    popa
    stc
    ret
.tmp    dw 0

这是存储所有这些信息的地方。现在你知道 Mike 是从哪里弄来的 mov word bx, [di+28].

byte [di+11], 0     ; Attributes             AL
byte [di+12], 0     ; Reserved
byte [di+13], 0     ; Reserved
byte [di+14], 0C6h  ; Creation time         \CX
byte [di+15], 07Eh  ; Creation time         /
byte [di+16], 0     ; Creation date         \DX
byte [di+17], 0     ; Creation date         /
byte [di+18], 0     ; Last access date      \SI
byte [di+19], 0     ; Last access date      /
byte [di+20], 0     ; Ignore in FAT12
byte [di+21], 0     ; Ignore in FAT12
byte [di+22], 0C6h  ; Last write time       \DI
byte [di+23], 07Eh  ; Last write time       /
byte [di+24], 0     ; Last write date
byte [di+25], 0     ; Last write date
byte [di+26], 0     ; First logical cluster
byte [di+27], 0     ; First logical cluster
byte [di+28], 0     ; File size              \BX
byte [di+29], 0     ; File size              /
byte [di+30], 0     ; File size
byte [di+31], 0     ; File size

如果您想从命令行显示所有这些信息,就像您编写的 SERIAL 命令一样,您必须转换 returned 中的数字注册到文本中,piece-a-cake!

此外,如果您将代码添加到 DISK.ASM 并更新 [,您的代码可以成为 api 的扩展=45=] table 在 KERNEL.ASM.

您可以通过查看执行与您想要执行的操作类似的现有代码来学到很多东西