Timer time data conversion sub-ProgramAnalysis
When reading a TSR program and analyzing a program segment that converts timer data in the BIOS data area to HH: mm: SS time format (ASCII, I learned something and found a problem that I cannot understand. Now, I want to write out what I learned and share it with you. I also want to consult with other experts.
The program snippets are as follows: (Assembly Language Program)
... (Omitted)
HMS dB 8 DUP (':')
...
Time proc
Lea Di, position; (1) -- row number
MoV ax, 0; (2)
MoV ds, ax; (3)
MoV Al, DS: [46eh]; (4)
Call clk1; (5)
MoV ax, DS: [46ch]; (6)
MoV dx, 0; (7)
MoV BX, 444 h; (8)
Call clk0; (9)
MoV ax, DX; (10)
MoV CX, 3ch; (11)
Mul CX; (12)
Clk0:
Add Di, 3; (13)
Div BX; (14)
Clk1:
AAM; (15)
Add ax, 3030 h; (16)
Xchg ah, Al; (17)
MoV Cs: [di], ax; (18)
RET; (19)
Time endp
The principle of program fragment implementation is to interrupt the int 1ch clock of BIOS to the 0040: 006ch (low word) and 0040: 006eh (high word) established in the BIOS data zone) the value in the 32-bit time counter is converted to the HH: mm: SS time format (ASCII characters) in a concise manner ), use another display subroutine to display the converted characters on the screen.
Int1ch interruption occurs every 55 milliseconds. When an interruption occurs, add the content of the 32-bit time digital counter of 0040: 006ch--0040: 006eh plus one, 24 hours a day, the maximum count value is 001800b0h. When the maximum value is reached, int1ch resets the counter to 0 and then recalculates the count. The next day begins.
Assume the value of a time counter to analyze the execution process of the preceding program fragment. Suppose [0040: 006eh] = 0017 H, [0040: 006eh] = 1aa3h. The execution process of the program fragment is as follows:
{(1)-> (4)}-> {(15)-> (19)}-> {(6)-> (8)}-> {(13) -> (19)}-> {(10)-> (19 )}
(The numbers in parentheses are row numbers, the arrows in braces are sequence instructions, and the arrows outside braces are instructions)
(1)-> (3): DS = AX = 0, DI = HMS displacement. HMS is the memory unit used to store the converted time value (ASCII.
(4): mov Al, DS: [46eh] That is, Al = 17 h
(5): Call clk1; call clk1
The execution process of clk1 is as follows: (15)-> (19). The Hour value is converted)
(15): AAM command, ASCII Adjustment Command of multiplication, adjust the value in Al to a non-compressed BCD format, that is, divide Al by 0ah (10), and store it in AH, place the remainder in Al. after execution, Ax = 0203 H.
(16): Add ax, 3030 h to make AX = 3233 H, which is the ASCII value of 2 and 3.
(17): xchg ah, Al order AX = 3332 H.
(18): mov Cs: [di]. Ax stores the converted value (ASCII) in the HMS.
(19): Ret returns. (return and execute the 6th command)
At this time, HMS is ':', ':', '3 ', '2' (low words)
(6): mov ax, DS: [46ch] AX = 1aa3h
(7), (8): BX = 444 H, dx = 0
(9): Call clk0; call clk0
The execution process of clk0 is as follows: (13)-> (19). The minute value is converted)
(12): Add Di, 3 add di to 3, that is, add 3 to the HMS pointer.
(14): div BX divides 1aa3h by 444 H. 444 H = 1092,1092/18.2 = 60 (seconds ). after the command is executed, Ax = 06 h (vendor), dx = 10bh (remainder)
(15 )... (19): Execute clk1. the execution process is the same as the preceding description. Convert AX = 06 h (minutes) to the displayed ASCII value. (19) The RET clause returns to the (10) clause.
At this time, HMS is ':', '6', '0', ':', '3 ', '2' (low words)
Start to convert the second value:
(10), (11): AX = 10bh, Cx = 3ch. (3ch = 60)
(12): 10bh * 3ch = 3e94, Ax = 3e94h
(13 )... (19): Execute clk0.( 14) Div BX; 3e94h/444 h ax = 0eh, dx = 2dch again. perform clk1 for the third time and convert AX = 0eh (14) to printable ASCII characters. the process is the same as above. (19) RET returns the call time
Subroutine. From (10) to (14) 267*60/1092 = 267/18. 2, (10bh = 267) indicates the number of seconds equivalent to 267 interruptions.
Finally, HMS is '4', '1', ':', '6', '0', ':', '3 ', '2' (low-text). The time is 23:06:14.
As can be seen from the above, the high [0040: 006eh] is the time value, and the low word [0040: 006ch] Is 65520 interruptions occurred in one hour. The above conversion process is clear. In 0040: 006eh-0040: 006ch, clk1 is directly called to convert a high-text string to a visible character. The lower word is divided by 444 H (times/minutes) to obtain the minute value (operator), and then clk1 is called to convert it into a visible character. Then, multiply the remainder (the number of interruptions in less than one minute) by 3ch and divide it by 444 H, that is, divide the remainder by 18.2 (times/second) to the second value (quotient ), the last time clk1 is called, it is converted to a visual character. The converted characters exist in the HMS memory unit.
Subroutine timeAlgorithmIt is easy to understand, but I am not clear about the int1ch interrupted execution process, and there are no relevant reference documents. I still cannot solve some questions, I would like to invite you to the super prawns (lobster ?) Ask. Thank you!