gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-03 06:30:37 26 4
gpt4 key购买 nike

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

  • 属性字节。
  • 创建时间。
  • 创建日期
  • 上次访问日期
  • 上次写入时间
  • 文件大小(以字节为单位)

我应该在其中添加 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 调用来轻松完成此任务。
对于您的任务,您不仅返回 BX 中的文件大小,还返回您选择的任何其他寄存器中的其他信息。
这可能是这样的选择:

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 单词 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 命令一样,您必须将返回的寄存器中的数字转换为文本,小菜一碟!

此外,如果您将代码添加到DISK.ASM并更新KERNEL.ASM<中的os_call_vectors表,您的代码可以成为API的扩展/em>.

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

关于assembly - 系统调用所请求文件的 INFO(如果存在),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57030830/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com