Unregistered
|
Мужики, спасайтею. Написал тут 2 проги на ASMе (TASM 1.0) а они компилироваться не хотят - ошибки выдают  . Помощь ваша нужна просто по-зарез, горю - готов уже повесится...PLS HELP ME _____________________________________________________________________________________________________________ 1)каждую секунду программа проверяет биты в регистрах AX, BX, CX, DX. для сохранения данных создан массив размером 64 dw, один word для каждого бита. каждую секунду программа проверяет биты в каждом из выше перечисленных регистров, если бит равен единице то ячеика отведенная для этого бита в массиве увеличивается на один. Программа должна работать на протяжение часа. | Код | .MODEL LARGE
.DATA
; Screen messages to display to the user.
prompt_string DB 'Please enter the time interval in seconds,',13,10 DB 'no more than 3600 seconds ( an hour ): $'
error_string DB 13,10,10,'Input error! The interval' DB ' set to 60 seconds ( a minute ).',13,10,'$'
report_string DB 13,10,'Final report:',13,10,'$'
ax_string DB 13,10,'AX:$' bx_string DB 13,10,'BX:$' cx_string DB 13,10,'CX:$' dx_string DB 13,10,'DX:$'
finish_string DB 13,10,10,'Finished.',13,10,'$'
; Three constants for technical needs. hundred DW 100 ten DW 10 const182 DW 182
;============================================================================= ;=============================================================================
.CODE
;-------------------------------------------------------------------------- ; 1. Declarations of variables to handle interrupt 8 and counting. ;--------------------------------------------------------------------------
; Array of counters initialized by zeroes: count_array DW 16 DUP (0) ; 16 counters for 16 bits of AX , DW 16 DUP (0) ; 16 for BX , DW 16 DUP (0) ; 16 for CX , DW 16 DUP (0) ; 16 for DX .
n_ticks DW 0 ; Ticks from the beginning, initially zero. max_ticks DW (?) ; Ticks in the requested time interval.
oldint8_seg DW (?) ; For old ISR 8 address. oldint8_offset DW (?) ;
flag DB 1 ; 1 - the counting continues, 0 - finished.
;-------------------------------------------------------------------------- ; 2. 'analyse_word' - extract bits from the word given in AX, increment ; corresponding counters in count_array from count_array[SI] (SI given). ;--------------------------------------------------------------------------
analyse_word PROC FAR ; ( Arguments: AX - the word to analyse, ; SI - the index of the first counter. )
PUSH BX ; PUSH CX ; Preserve registers. PUSH DX ; BX will be the mask for extracting bits, MOV BX, 1 ; starts from 0000000000000001b.
MOV CX, 16 ; There are 16 bits in the word.
analyse_loop: ; Loop over all bits: ; MOV DX, AX ; Copy the word to DX. AND DX, BX ; Extract a bit. DX becomes 0 iff the bit CMP DX, 0 ; matching '1' in the mask is 0; if so JE next_bit ; then go to the next bit... ; MOV DX, count_array[SI] ; ... otherwise: INC DX ; increment the corresponding counter. MOV count_array[SI], DX ; ; next_bit: ; Go to the next bit: ADD SI, 2 ; a) Move to the next counter ( 2 bytes ). SHL BX, 1 ; b) Move '1' in the mask one position to left. LOOP analyse_loop ; c) Do next iteration. POP DX ; POP CX ; Restore registers... POP BX ; RET ; ... and return. analyse_word ENDP
;-------------------------------------------------------------------------- ; 3. 'newint8' routine - at each clock tick analyse bits in AX,BX,CX,DX , ; increment n_ticks, signal when the time interval elapses. ;--------------------------------------------------------------------------
newint8 PROC FAR
PUSH ES ; PUSH DI ; PUSH SI ; PUSH DX ; Preserve registers. PUSH CX ; PUSH BX ; PUSH AX ;
MOV AX, oldint8_seg ; MOV ES, AX ; MOV BX, oldint8_offset ; Call old ISR 8. PUSHF ; CALL FAR PTR ES:BX ;
MOV AX, n_ticks ; INC AX ; Increment n_ticks. CMP AX, max_ticks ; If max_ticks reached... JG stop_counting ; ... then stop the counting.
continue_counting: ; otherwise: MOV n_ticks, AX ; a) Save the incremented value. MOV SI, 0 ; b) The first counter will be No 0. POP AX ; c) Get the original value of AX for analysis. MOV DI, AX ; d) Preserve it in DI. CALL analyse_word ; e) Analyse AX. ; POP AX ; f) Get the original value of BX for analysis. CALL analyse_word ; g) Analyse it. ( The loop in 'analyse_word' ; advanced SI exactly to the ; counters corresponding BX. ) MOV BX, AX ; h) Restore it to BX. ; POP AX ; i) Get the original value of CX for analysis. CALL analyse_word ; j) Analyse it. MOV CX, AX ; k) Restore it to CX. ; POP AX ; l) Get the original value of DX for analysis. CALL analyse_word ; m) Analyse it. MOV DX, AX ; n) Restore it to DX. ; MOV AX, DI ; o) Restore the original value of AX. JMP finish8 ; p) Finish ISR 8.
stop_counting: ; When the counting stops: XOR AX, AX ; MOV ES, AX ; MOV AX, oldint8_offset ; a) Restore old ISR addresses in the IV. MOV BX, oldint8_seg ; CLI ; MOV ES:[8*4], AX ; MOV ES:[8*4+2], BX ; STI ; XOR AL, AL ; b) Zero the flag to signal the main program MOV flag, AL ; that the counting finished. POP AX ; POP BX ; c) Restore AX,BX,CX,DX . POP CX ; POP DX ; finish8: ; The common end: POP SI ; POP DI ; restore SI,DI,ES ... POP ES ; IRET ; ... and return.
newint8 ENDP
;-------------------------------------------------------------------------- ; 4. 'display_number' - display an integer ( a word ) in AX on the screen. ;--------------------------------------------------------------------------
display_number PROC FAR; ( Argument: AX - the value to display. )
PUSH DX ; Preserve registers. PUSH BX ;
output_loop: ; XOR DX, DX ; Zero DX for correct division. DIV ten ; Extract the last decimal digit of AX: ; AX gets the integer part of (AX/10), ; DX ( actually DL ) gets the residual. MOV BX, AX ; Preserve the integer part in BX. ADD DL, '0' ; Actually DL holds the last digit; convert it to ; ASCII code of the corresponding character... MOV AH, 2 ; INT 21h ; ... and display it on the screen. ; MOV AX, BX ; Restore the integer part for the next iteration. CMP AX, 0 ; If there are still digits in the number... JNE output_loop ; ... then go to the next iteration.
POP BX ; Restore registers... POP DX ; RET ; ... and return. display_number ENDP
;-------------------------------------------------------------------------- ; 5. 'report' - for each bit in AX,BX,CX,DX display the percent of clock ; ticks in which it was 1. ;--------------------------------------------------------------------------
report PROC FAR PUSH AX ; PUSH SI ; Preserve registers. PUSH CX ; PUSH DX ; PUSH DS ;
MOV SI, 0 ; SI will be an index in count_array, ; starts from zero.
MOV DX, SEG report_string ; MOV DS, DX ; Display 'report' string for the user. MOV DX, OFFSET report_string; MOV AX, 9 ; INT 21h ;
MOV DX, SEG ax_string ; MOV DS, DX ; Display 'AX:' string for the user. MOV DX, OFFSET ax_string ; MOV AX, 9 ; INT 21h ; MOV CX, 16 ; There are 16 bits in AX. display_ax_loop: ; MOV DL, ' ' ; Space to separate between numbers. MOV AH, 2 ; INT 21h ; MOV AX, count_array[SI] ; Get the value n of a counter. MUL hundred ; DX:AX<-100*n : Convert to percents: DIV max_ticks ; AX<-100*n/max_ticks : (percent among all ticks) = ; 100*(counter value)/(num.ticks). CALL display_number ; Display on the screen. ADD SI, 2 ; Move to the next counter ( 2 bytes ). LOOP display_ax_loop ;
MOV DX, SEG bx_string ; The same things for BX statistics. MOV DS, DX ; MOV DX, OFFSET bx_string ; MOV AX, 9 ; INT 21h ; MOV CX, 16 ; display_bx_loop: ; MOV DL, ' ' ; MOV AH, 2 ; INT 21h ; MOV AX, count_array[SI] ; ( In the previous loop SI arrived exactly MUL hundred ; to the counters that hold BX statistics. ) DIV n_ticks ; CALL display_number ; ADD SI, 2 ; LOOP display_bx_loop ;
MOV DX, SEG cx_string ; The same things for CX statistics. MOV DS, DX ; MOV DX, OFFSET cx_string ; MOV AX, 9 ; INT 21h ; MOV CX, 16 ; display_cx_loop: ; MOV DL, ' ' ; MOV AH, 2 ; INT 21h ; MOV AX, count_array[SI] ; MUL hundred ; DIV n_ticks ; CALL display_number ; ADD SI, 2 ; LOOP display_cx_loop ;
MOV DX, SEG dx_string ; The same things for DX statistics. MOV DS, DX ; MOV DX, OFFSET dx_string ; MOV AX, 9 ; INT 21h ; MOV CX, 16 ; display_dx_loop: ; MOV DL, ' ' ; MOV AH, 2 ; INT 21h ; MOV AX, count_array[SI] ; MUL hundred ; DIV n_ticks ; CALL display_number ; ADD SI, 2 ; LOOP display_dx_loop ;
POP DS ; POP DX ; Restore registers... POP CX ; POP BX ; POP AX ; RET ; ... and return. report ENDP
;-------------------------------------------------------------------------- ; 6. 'input_time_interval' - the user inputs a positive integer number of ; seconds in the requested time interval, the number returns in AX; ; if it was not in the range 1...3600 seconds, the routine sets it to 60. ;--------------------------------------------------------------------------
input_time_interval PROC FAR ; ( Returned value: AX - number of seconds. )
PUSH BX ; PUSH CX ; Preserve registers. PUSH DX ; PUSH DS ; The number will be built digit-by-digit XOR AX, AX ; in AX; starts from zero. input_loop: ; Each iteration adds a digit at the end ; of AX ( e.g. AX=123,input '4' -> AX=1234 ) MOV DX, AX ; Preserve the previous value (123) in DX. MOV AH, 1 ; Get the next datum from the keyboard INT 21h ; AL<-'4' ( it arrives to AL ). CMP AL, 13 ; If it is ENTER... JE end_input ; ... then the input ends. ; Otherwise: convert the ASCII code ADD AL, '0' ; AL<-4 of a digit to the digit itself MOV BL, AL ; and copy it to BL... MOV BH, 0 ; ... and to BX. ( BX=4 ) MOV AX, DX ; Restore the previous value in AX (AX<-123). MUL ten ; AX<-1230 JO input_error ; If overflow ( number too big ) then error. ADD AX, BX ; AX<-1234 JO input_error ; If overflow ( number too big ) then error. JMP input_loop ; Otherwise go to the next iteration.
end_input: ; When the input ends: CMP AX, 3600 ; a) If it is too big... JG input_error ; ... then it is an error. CMP AX, 0 ; b) If the number is really positive... JG return_number ; ... then return it.
input_error: ; If there was any error: MOV DX, SEG error_string ; MOV DS, DX ; MOV DX, OFFSET error_string; MOV AH, 9 ; a) Display the error message. INT 21h ; MOV AX, 60 ; b) Set the number to be 60 seconds.
return_number: ; In any case: POP DS ; POP DX ; Restore registers... POP CX ; POP BX ; RET ; ... and return ( return AX ). input_time_interval ENDP
;-------------------------------------------------------------------------- ; 7. The main program - input time interval from the user, set new ISR 8 ; that will count how many times each bit in AX,BX,CX,DX was 1 at ; clock ticks during this interval, then display the results. ;--------------------------------------------------------------------------
main: MOV AX, @DATA MOV DS, AX MOV AX, 0 ; MOV ES, AX ; Point to segment 0. MOV AX, ES:[8*4] ; MOV DWORD PTR oldint8_offset; Save old ISR 8 address. MOV AX, ES:[8*4+2] ; MOV DWORD PTR oldint8_seg ; MOV DX, OFFSET prompt_string; MOV AH, 9 ; Prompt the user to enter the time interval. INT 21h ; CALL input_time_interval ; Input the time interval from the user ; ( the value t returned in AX ). MUL const182 ; DX:AX <- t*182 : DIV ten ; AX <- t*18.2 : Convert seconds to ticks. MOV max_ticks, AX ; max_ticks gets the time interval in ticks.
MOV AX, OFFSET newint8 ; MOV BX, SEG newint8 ; Compute new ISR 8 address. CLI ; MOV ES:[8*4], AX ; Write the new addresses to the IV. MOV ES:[8*4+2], BX ; STI ; The counting starts here. waiting_loop: ; The main program begins to wait... MOV AX, flag ; CMP AX, 0 ; ... until flag=0 ( newint8 will signal JNE waiting_loop ; the end by setting flag<-0 )
CALL report ; Display the results when the counting stops.
MOV DX, OFFSET finish_string; MOV AH, 9 ; Display the message 'Finished'. INT 21h ;
MOV AH, 4Ch ; Terminate the program. INT 21h ; ( IV was restored in newint8. ) END main
|
2)программа не позволяет медленно вводить данные с клавиатуры, после каждого ввода измеряеться время до следущего ввода если прошло больше 1.5 минуты, клавиатура блокируется, и только после нажатия enter можно продолжить ввод данных. Программа будет измерять время до нажатие на esc. | Код | .MODEL LARGE
.DATA ; Screen messages for the user.
prompt_string DB 'Please enter text.',13,10,10,'$' DB 'Please keep such a rate that intervals between',13,10,'$' DB 'each two key pressings will not be longer than',13,10,'$' DB '100 clock ticks.',13,10,10,'$' DB 'Press ESC to finish.',13,10,'$'
too_long_string DB 13,10,10,'Time too long. Keyboard locked.' DB ' Press ENTER to release.',13,10,10,'$'
finish_string DB 13,10,10,'Finished.',13,10,'$'
;============================================================================= ;=============================================================================
.CODE
;-------------------------------------------------------------------------- ; 1. Declarations of constants and variables to handle interrupts 8 and 9. ;--------------------------------------------------------------------------
t EQ 100 ; Maximal number of ticks allowed. n_ticks DW 0 ; Ticks counter since last key pressing.
oldint8_seg DW (?) ; For old ISR 8 address. oldint8_offset DW (?) ;
free EQ 1 ; locked EQ 0 ; Keyboard status. keyboard_status DB free ;
oldint9_seg DW (?) ; For old ISR 9 address. oldint9_offset DW (?) ;
;-------------------------------------------------------------------------- ; 2. 'newint8' routine - increment n_ticks, lock keyboard when time elapses. ;--------------------------------------------------------------------------
newint8 PROC FAR
PUSH ES ; PUSH BX ; Preserve registers. PUSH AX ;
MOV AX, oldint8_seg ; MOV ES, AX ; MOV BX, oldint8_offset ; Call old ISR 8. PUSHF ; CALL FAR PTR ES:BX ;
MOV AL, keyboard_status ; CMP AL, locked ; If the keyboard is locked... JE finish8 ; ... then no action needed.
MOV AX, n_ticks ; Increment n_ticks. INC AX ; CMP AX, t ; If the time elapsed... JLE time_too_long ; ...then go to this case.
time_ok: ; If the time is OK: MOV n_ticks, AX ; Save the new value of n_ticks. JMP finish8 ; No more action needed.
time_too_long: ; If the time elapsed: MOV AL, locked ; MOV keyboard_status, AL ; a) Lock the keyboard.
PUSH DS ; PUSH DX ; MOV AX, SEG too_long_string ; MOV DS, AX ; MOV DX, OFFSET too_long_string; MOV AH, 9 ; b) Display the message 'Time too long' INT 21h ; on the screen. POP DX ; POP DS ;
finish8: ; The common end for all the cases: POP AX ; POP BX ; Restore registers... POP ES ; IRET ; ... and return.
newint8 ENDP
;-------------------------------------------------------------------------- ; 3. 'newint9' routine - start a new counting of n_ticks; if the keyboard ; is locked then ignore key pressing but release keyboard when ENTER. ;--------------------------------------------------------------------------
newint9 PROC FAR
PUSH AX ; PUSH BX ; Preserve registers. PUSH ES ;
MOV AL, keyboard_status ; CMP AX, locked ; If the keyboard is locked... JE when_keyboard_locked ; ... then go to this case.
when_keyboard_free: ; If the keyboard is free: MOV AX, oldint9_seg ; MOV ES, AX ; MOV BX, oldint9_offset ; PUSHF ; CALL FAR PTR ES:BX ; a) Call usual ISR 9. XOR AX, AX ; MOV n_ticks, AX ; b) Start a new counting by zeroing n_ticks. JMP finish9 ;
when_keyboard_locked: ; If the keyboard is locked: MOV AH, 0 ; INT 16h ; a) Get the next data. CMP AL, 13 ; b) If it is anything but ENTER... JNE finish9 ; ... then ignore it. ; Otherwise: XOR AX, AX ; c) Zero n_ticks. MOV n_ticks, AX ; ( AH remains 0 here - for INT 16h. ) INT 16h ; d) Get ASCII 10 from the buffer. MOV AL, free ; ( ENTER generates 13,10 in the buffer. ) MOV keyboard_status, AL ; e) Release the keyboard.
finish9: ; The common end: POP ES ; POP BX ; Restore registers... POP AX ; IRET ; ... and return. newint9 ENDP
;-------------------------------------------------------------------------- ; 4. The main program - set new ISR 8 and 9, input text from the keyboard ; until ESC. ;--------------------------------------------------------------------------
main: MOV AX, @DATA MOV DS, AX MOV AX, 0 ; MOV ES, AX ; Point to segment 0. MOV AX, ES:[8*4] ; MOV DWORD PTR oldint8_offset; Save old ISR 8 address. MOV AX, ES:[8*4+2] ; MOV DWORD PTR oldint8_seg ; MOV AX, ES:[9*4] ; MOV DWORD PTR oldint9_offset; Save old ISR 9 address. MOV AX, ES:[9*4+2] ; MOV DWORD PTR oldint9_seg ; MOV AX, OFFSET newint8 ; MOV BX, SEG newint8 ; Compute new ISR 8 and 9 addresses. MOV CX, OFFSET newint9 ; MOV DX, SEG newint9 ; CLI ; MOV ES:[8*4], AX ; MOV ES:[8*4+2], BX ; Write the new addresses to the IV. MOV ES:[9*4], CX ; MOV ES:[9*4+2], DX ; STI ; MOV DX, OFFSET prompt_string; MOV AH, 9 ; Prompt the user to enter text. INT 21h ;
text_input_loop: ; MOV AX, 1 ; INT 21h ; Wait for a text input... CMP AL, 27 ; JNE text_input_loop ; ... until ESC. MOV AX, oldint8_offset ; MOV BX, oldint8_seg ; MOV CX, oldint9_offset ; MOV DX, oldint9_seg ; CLI ; MOV ES:[8*4], AX ; MOV ES:[8*4+2], BX ; Restore old ISR addresses in the IV. MOV ES:[9*4], CX ; MOV ES:[9*4+2], DX ; STI ;
MOV DX, OFFSET finish_string; MOV AH, 9 ; Display the message 'Finished'. INT 21h ;
MOV AH, 4Ch ; INT 21h ; Terminate the program.
END main
|
HELP KTO MO}|{ET!!!!
|