On a regular win xp pro pc (pentium 4), - a code that takes date and time from the Real Time Clock and prints it to the scren.
Thanks a lot.
Amir
.386
.model small
.data
resbeg db 'day, hour, minute, second'
res db 3 dup (?)
resend db '$'
.stack
dw 100 dup (?)
.code
start:
; Defines data and code and stack segments.
mov ax, @data
mov ds, ax
mov ax, @code
mov cs, ax
mov ax, @stack
mov ss, ax
; Reads seconds from RTC and puts it in the last index of res.
mov al, 00h
out 70h, al
in al, 71h
mov res[3], al
mov al, 02h
out 70h, al
in al, 71h
mov res[2], al
mov al, 04h
out 70h, al
in al, 71h
mov res[1], al
mov al, 06h
out 70h, al
in al, 71h
mov res[0], al
; Prints out entire vector.
mov dx, offset @data
mov ah, 9
int 21h
end start
The first problem is the position of the .386 processor directive relative to the .MODEL directive. When a .386 or later processor directive precedes the .MODEL directive it not only enables assembly of the processor's instruction set, but also sets the offset address size to 32 bits, which will not work for 16-bit code. The solution is to place the processor directive below the .MODEL directive.
The second problem is in the code that loads the segment registers. The MOV instruction cannot be used to load the CS segment register, so when the processor attempts to execute:
mov cs, ax
It triggers an invalid opcode exception, and the system pops us a message box stating that the NTVDM CPU has encountered an illegal instruction. Since the program loader takes care of loading the correct segment address into CS, the solution is to simply remove the:
mov ax, @code
mov cs, ax
And since the program loader will also set up a workable stack, you can also remove the:
mov ax, @stack
mov ss, ax
The third problem is that your code is not converting the day, hour, minute, and second values to digits before it attempts to display them. Since the values are Binary Coded Decimal (BCD), where each digit value is represented by 4 bits, the conversion is simple - you isolate each 4-bit value in a byte register and add the ASCII character code for the decimal digit 0 (30h). The following code converts the BCD value less than 100 decimal in AL to two decimal digits, and uses Interrupt 21h function 2 to display the digits.
push ax ; preserve AL
shr al, 4 ; isolate high-order 4 bits
add al, 30h ; convert to decimal digit
mov ah, 2 ; use function 2 to display
mov dl, al
int 21h
pop ax ; recover AL
and al, 0fh ; isolate low-order 4 bits
add al, 30h ; convert to decimal digit
mov ah, 2 ; use function 2 to display
mov dl, al
int 21h
And the fourth problem is that your program is not terminating properly. The common way of doing this would be to call Interrupt 21h function 4Ch.