Question

In my project I need to use inline Assembly, but it need to be Nasm, because I'm not too much familiar with GAS.
My try:

void DateAndTime()
{
   asm
   (.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);
}

There is any way to do this but using Nasm instead of GAS?

I think I need to add a argument when compiling.

Was it helpful?

Solution

I did a quick google on 'nasm + gcc', have a look here, here, and here.

In a nutshell the switches to be used for nasm in order to link along with the gcc compiled object is:

nasm -f elf

Edit: The above was absolutely irrelevant as Nathan was looking for a GAS syntax similar to the code snippet in the question..here is my attempt of the GAS'ified version...

void DateAndTime()
{
   int RTCaddress, RTCdata, RTCtimeSecond, RTCtimeHour, RTCtimeMinute, RTCtimeDay, RTCtimeMonth, RTCtimeYear;
   // Set RTCaddress and RTCdata respectively first...
   RTCaddress = 0x70;
   RTCdata = 0x71; 
   asm
   (
.l1:    
    movb $10, %al           ;Get RTC register A
    out %al, RTCaddress        ; Think RTCaddress needs to be declared...
    in RTCdata, %al            ; RTCdata needs to be declared
    test $80, %al            ;Is update in progress?
    jne .l1             ; yes, wait

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

    movb $2, %al         ;Get minutes (00 to 59)
    out %al, RTCaddress
    in RTCdata, %al
    movb %al, [RTCtimeMinute]

    movb $4, %al         ;Get hours (see notes)
    out %al, RTCaddress
    in RTCdata, %al
    movb %al, [RTCtimeHour]

    movb $7, %al         ;Get day of month (01 to 31)
    out %al, RTCaddress
    in RTCdata, %al
    movb %al, [RTCtimeDay]

    movb $8, %al         ;Get month (01 to 12)
    out %al, RTCaddress
    in RTCdata, %al
    movb %al, [RTCtimeMonth]

    movb $9, %al         ;Get year (00 to 99)
    out %al, RTCaddress
    in RTCdata, %al
    movb %al, [RTCtimeYear]

    ret);

Judging by the BIOS data where the RTC clock is, ports used is 0x70, 0x71 which I have used here... I may be wrong...

OTHER TIPS

GCC uses AT&T syntax while NASM uses Intel syntax.

If you find you need to manually convert between the two formats the objdump and ndisasm tools will come in very handy. Just assemble in the current format, disassemble in the target format, then fix up any machine-generated craziness added by the disassembler.

If you're going to AT&T syntax specifically, it may be helpful to look at the disassembly in GDB instead of using objdump.

As this came top of my search I'll add the relevant info:

Go see Can I use Intel syntax of x86 assembly with GCC?

GCC also has "-fverbose-asm", "-fno-asynchronous-unwind-tables" and "-fconserve-stack" which may make generated assembler an easier read.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top