3

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.

Nathan Campos
  • 28,769
  • 59
  • 194
  • 300
  • 1
    It looks like you're writing in more assembly than C. Why do you want to put this inline in a C file, instead of separating it out entirely? – ephemient Jan 21 '10 at 02:13

3 Answers3

5

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.

Dan Olson
  • 22,849
  • 4
  • 42
  • 56
1

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...

t0mm13b
  • 34,087
  • 8
  • 78
  • 110
  • But I need to be as inline code to be used inside a function. – Nathan Campos Jan 21 '10 at 01:42
  • 1
    @Nathan@ Ok... sorry for the misleading answer...can you post the actual assembler code and I'll try GAS'ify it? – t0mm13b Jan 21 '10 at 01:44
  • 1
    There may be typos in there...in GAS, the syntax is mnemonic src, dest, MASM/TASM is the reverse i.e. mnemonic dest, src. Mnemonics prefixes are b, s, i, l (byte, short, int, long) respectively. Registers are prefixed with %. Numbers as constants are prefixed with $. – t0mm13b Jan 21 '10 at 02:24
  • 1
    Please have a look here... http://en.wikibooks.org/wiki/X86_Assembly/GAS_Syntax, for further details...that's my basic knowledge of GAS which I have learnt from the above link... – t0mm13b Jan 21 '10 at 02:26
  • This is not how GNU C inline `asm("template" : outputs : inputs : clobbers)` works for accessing C variables, unlike MSVC you can't just use C var name in your asm code. https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html and https://stackoverflow.com/tags/inline-assembly/info . It's also not valid AT&T syntax for many instructions, e.g. AT&T doesn't use square brackets for memory operands. https://stackoverflow.com/tags/att/info or look at GCC output. And `movb` to store to the low byte of an `int` variable leaves the upper 3 bytes holding uninitialized garbage. – Peter Cordes Feb 21 '23 at 01:20
  • [GNU assembler syntax for IN and OUT instructions](https://stackoverflow.com/q/46137148) has an example of *part* of what this needs to be, without C variable outputs. – Peter Cordes Feb 21 '23 at 01:21
1

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.

Community
  • 1
  • 1
user3710044
  • 2,261
  • 15
  • 15