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
ortimes (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
Async Connect and Disconnect with Epoll (Linux)
Nginx Not Listening to Port 80
How to Delete Files Older Than Specific Date in Linux
Ldconfig Equivalent in MAC Os X
Limiting Certain Processes to CPU % - Linux
Thousands of Images, How to Organize the Directory Structure? (Linux)
Git: Can't Push (Unpacker Error) Related to Permission Issues
Encrypt a String Using Openssl Command Line
Installing R from Cran Ubuntu Repository: No Public Key Error
Error with Gradlew: /Usr/Bin/Env: Bash: No Such File or Directory
What Should Linux/Unix 'Make Install' Consist Of
Percentage Value with Gnu Diff
How to Insert New Line in the Email Using Linux Mail Command
Run a Shell Script from Docker-Compose Command, Inside the Container
Bash VS Csh VS Others - Which Is Better for Application Maintenance