How to Access System Time Using Nasm

How can I access system time using NASM?

On bare metal (in a custom OS), or in a DOS program:

%define RTCaddress  0x70
%define RTCdata 0x71

;Get time and date from RTC

.l1: mov al,10 ;Get RTC register A
out RTCaddress,al
in al,RTCdata
test al,0x80 ;Is update in progress?
jne .l1 ; yes, wait

mov al,0 ;Get seconds (00 to 59)
out RTCaddress,al
in al,RTCdata
mov [RTCtimeSecond],al

mov al,0x02 ;Get minutes (00 to 59)
out RTCaddress,al
in al,RTCdata
mov [RTCtimeMinute],al

mov al,0x04 ;Get hours (see notes)
out RTCaddress,al
in al,RTCdata
mov [RTCtimeHour],al

mov al,0x07 ;Get day of month (01 to 31)
out RTCaddress,al
in al,RTCdata
mov [RTCtimeDay],al

mov al,0x08 ;Get month (01 to 12)
out RTCaddress,al
in al,RTCdata
mov [RTCtimeMonth],al

mov al,0x09 ;Get year (00 to 99)
out RTCaddress,al
in al,RTCdata
mov [RTCtimeYear],al

ret

This uses NASM, and is from here.

This will not work under a normal OS like Linux that stops user-space processes from directly accessing hardware. You could maybe get this to work as root, with an ioperm(2) system call to allow access to that I/O port. Linux only updates the BIOS/hardware RTC to match the current system time during shutdown, not continuously, so don't expect it to be perfectly in sync, especially if the motherboard battery is dead.

Assemble-time read the value of a data variable

That's not how assembly language works. It assembles bytes into the output file, and there's no way to read back those bytes at assemble time. "Variable" is a high-level concept which you can implement in asm, but isn't natively supported1.

If you want to have multiple things depend on the same value,

use foo equ 123 to define an assemble-time constant you can use later in multiple places.

To assemble some bytes in data memory with that value, use bar: dw foo.

It's an assemble-time constant so you can do things like resb foo*512 or

times (512*foo-511)-($-begin_main_program)

If you only did bar: dw 123, there'd be no way to get at the 123 while assembling other lines. (The bar: label is separate from the dw 123 or db 123, 0 or whatever you choose to put before or after it. It gives you a way to refer to that address from elsewhere, e.g. dw bar to assemble a pointer, or mov ax, [bar] to assemble an instruction that at run-time will load from that absolute address.)


Footnote 1: Except in NASM's macro language, with stuff like %assign i i+1 - useful inside a %rep 10 / %endrep block.

https://nasm.us/doc/nasmdoc4.html#section-4.1.8



Related Topics



Leave a reply



Submit