Пользователь
Регистрация: 09.01.2024
Сообщений: 18
|
Собрать программу, код готовый.
Чередующиеся участки на случай IBM.
Параграфы, уделение памяти.
Ничего особенно сложного, пять обычных задач, но в сумме.
Полагаю, наглядно можно за две-три минуты определить код и сказать как он правильно соберётся.
Сомневаюсь, что у кого-либо есть готовое решение.
Более подробное описание: https://github.com/microsoft/MS-DOS/...ource/EXEC.ASM
Почти ничего не изменив, добавил лишь объявления: модели памяти, сегмента данных, стека, сегмента кода. Иначе не получится собрать.
Код:
model large
.386
org 7C00h
.Data
exec_blk DD (?)
exec_func DB (?)
exec_fh DW (?)
exec_rel_fac DW (?)
exec_res_len_para DW (?)
exec_init_IP DW (?)
exec_init_CS DW (?)
exec_init_SP DW (?)
exec_init_SS DW (?)
exec_environ DW (?)
exec_size DW (?)
exec_load_block DW (?)
exec_load_high DB (?)
.EQU exec_internal_buffer, $ ; ( Объявление константы )
exec_signature DW (?)
exec_len_mod_512 DW (?)
exec_pages DW (?)
exec_rle_count DW (?)
exec_par_dir DW (?)
exec_min_BSS DW (?)
exec_max_BSS DW (?)
exec_SS DW (?)
exec_SP DW (?)
exec_chksum DW (?)
exec_IP DW (?)
exec_CS DW (?)
exec_rle_table DW (?)
exec_iov DW (?)
exec_dma DW (?)
Define_IBM DB 0
.EQU exec_internal_buffer_size, $-exec_internal_buffer ; ( Объявление следующей константы )
.Stack 0FFh
.Code
A:Mov AX,@Data
Mov DS,AX
Xor AX,AX
f: int_num
Cmp AL,(num)
JNE B
Mov Define_IBM,AL ; ( нужен/не нужен IBM)
End f
if_IBM:
PUSH CS
POP DS
ASSUME DS:EGROUP
MOV AX,(Set_Ctrl_C_Trapping SHL 8) + 0 ; Save current ctrl-c
INT int_command
MOV exec_ctrlc,DL
XOR DX,DX
MOV AX,(Set_Ctrl_C_Trapping SHL 8) + 1 ; Turn it off!
INT int_command
MOV AH,Get_current_PDB
INT int_command
MOV [CurrentPDB],BX
;
; set up user return stack info
;
MOV ES,BX
LES BX,DWORD PTR [user_sp]
MOV WORD PTR ES:[PDB_user_stack+2],ES
MOV WORD PTR ES:[PDB_user_stack],BX
MOV AH,Get_Default_Drive
INT int_command
MOV DL,AL
MOV AH,Set_default_drive
INT int_command
MOV [NUMIO],AL
;
; determine lowest seg address for overwrite problem (round DOWN)
;
MOV CL,4
MOV AX,OFFSET ZEXEC_CODE:exec_check
SHR AX,CL
PUSH CS
POP BX
ADD AX,BX
MOV [exec_low_seg],AX
CALL get_user_stack
ASSUME DS:NOTHING
MOV AX,[SI.user_AX]
MOV BX,[SI.user_BX]
MOV DX,[SI.user_DX]
MOV ES,[SI.user_ES]
MOV DS,[SI.user_DS]
END if_IBM
B:
CMP AL,3 ; only 0, 1 or 3 are allowed
JNA exec_check_2
if_Error:
exec_bad_fun:
error error_invalid_function
exec_ret_err:
transfer SYS_RET_ERR
End if_Error
exec_check_2:
CMP AL,2
JZ exec_bad_fun
MOV WORD PTR [exec_blk],BX ; stash args
MOV WORD PTR [exec_blk+2],ES
MOV BYTE PTR [exec_func],AL
MOV BYTE PTR [exec_load_high],0
Mov AL,DefineIBM
Cmp AL,0
JNZ not_IBM
if_IBM2:
MOV AX,(OPEN SHL 8) + 0
INT int_command
END if_IBM2
not_IBM:
XOR AL,AL ; open for reading
invoke $OPEN ; is the file there?
END not_IBM
JC exec_ret_err
MOV [exec_fh],AX
MOV BX,AX
Mov AL,DeifneIBM
Cmp AL,0
JNZ not_IBM2
if_IBM3:
MOV AX,(ioctl SHL 8) ; get device information
INT int_command
END if_IBM3
not_IBM2:
XOR AL,AL
invoke $IOCTL
END not_IBM2
TEST DL,devid_ISDEV
JZ exec_check_environ
MOV AL,exec_file_not_found
transfer SYS_RET_ERR
exec_check_environ:
MOV [exec_load_block],0
TEST BYTE PTR [exec_func],exec_func_overlay ; overlays... no environment
JNZ exec_read_header
LDS SI,DWORD PTR [exec_blk] ; get block
MOV AX,[SI].Exec1_environ ; address of environ
OR AX,AX
JNZ exec_scan_env
MOV DS,[CurrentPDB]
MOV AX,DS:[PDB_environ]
MOV [exec_environ],AX
OR AX,AX
JZ exec_read_header
exec_scan_env:
CLD
MOV ES,AX
XOR DI,DI
MOV CX,07FFFh ; at most 32k of environment
XOR AL,AL
exec_get_environ_len:
REPNZ SCASB ; find that nul byte
JZ exec_check ; CX is out... bad environment
MOV AL,exec_bad_environment
JMP exec_bomb
exec_check:
SCASB ; is there another nul byte?
JNZ exec_get_environ_len ; no, scan some more
PUSH DI
MOV BX,DI ; AX <- length of environment
ADD BX,0Fh
MOV CL,4
SHR BX,CL ; number of paragraphs needed
PUSH ES
Mov AL,DefineIBM
Cmp AL,0
JNZ not_IBM3
if_IBM4:
MOV AH,ALLOC
INT int_command
END if_IBM4
not_IBM3:
invoke $ALLOC ; can we get the space?
END not_IBM3
POP DS
POP CX
JNC exec_save_environ
JMP exec_no_mem ; nope... cry and sob
exec_save_environ:
MOV ES,AX
MOV [exec_environ],AX ; save him for a rainy day
; ( Чередующиеся участки: IBM или нет ) | ( параграфы, регистры, стек )
if_IBM5:
PUSH CX
MOV CX,ES
ADD CX,BX
CMP BX,[exec_low_seg]
POP CX
JA exec_no_mem
END if_IBM5
XOR SI,SI
XOR DI,DI
REP MOVSB ; copy the environment
exec_read_header:
;
; We read in the program header into the above data area and determine
; where in this memory the image will be located.
;
if_IBM6:
PUSH CS
POP DS ; and put it in DS:DX
ASSUME DS:EGROUP
END if_IBM6
; Сокращено.
CALL exec_alloc
POP DS
POP ES
JC exec_bad_file
CMP AX,exec_internal_buffer_size; did we read the right number?
JNZ exec_com_filej ; yep... continue
CMP [exec_max_BSS],0
JNZ exec_check_sig
MOV [exec_load_high],-1
exec_check_sig:
MOV AX,[exec_signature]
CMP AX,exe_valid_signature ; zibo arises!
JZ exec_save_start ; assume com file if no signature
CMP AX,exe_valid_old_signature ; zibo arises!
JZ exec_save_start ; assume com file if no signature
exec_com_filej:
JMP exec_com_file
;
; We have the program header... determine memory requirements
;
exec_save_start:
MOV AX,[exec_pages] ; get 512-byte pages
MOV CL,5 ; convert to paragraphs
SHL AX,CL
SUB AX,[exec_par_dir] ; AX = size in paragraphs
MOV [exec_res_len_para],AX
... ( Next part )
|