使用GCC的NASM内联汇编

3
在我的项目中,我需要使用内联汇编,但需要使用Nasm,因为我对GAS不太熟悉。
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);
}

有没有办法使用Nasm而不是GAS来完成这个任务?

我认为我需要在编译时添加一个参数。


1
看起来你写的汇编比C语言还多。为什么要把它内联在C文件中,而不是完全分离出来? - ephemient
3个回答

5

GCC使用AT&T语法,而NASM使用Intel语法。

如果你需要手动在两种格式之间进行转换,objdump和ndisasm工具将非常有用。只需在当前格式中汇编,在目标格式中反汇编,然后修复由反汇编器添加的任何机器生成的疯狂代码即可。

如果你要特别使用AT&T语法,使用GDB查看反汇编可能会更有帮助,而不是使用objdump。


1

我在谷歌上快速搜索了“nasm + gcc”,请看这里这里这里

简而言之,要与gcc编译的对象链接使用的nasm开关是:

nasm -f elf

编辑:以上内容与本题无关,因为Nathan正在寻找类似于问题中代码片段的GAS语法。这是我尝试将其转换为GAS版本的结果...

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);

根据BIOS数据中RTC时钟的信息,所使用的端口是0x70和0x71,本人已在此处使用...但我可能错了...

但是我需要将它作为内联代码,以便在函数内使用。 - Nathan Campos
1
@Nathan@ 好的...抱歉我之前回复有误...您能发一下实际的汇编代码吗?我会尝试将其转为GAS格式。 - t0mm13b
1
可能存在一些拼写错误...在GAS中,语法是助记符src,dest,MASM/TASM是相反的,即助记符dest,src。 助记符前缀分别是b,s,i,l(表示字节,短整型,整型,长整型)。 寄存器以%为前缀。 常量数字以$为前缀。 - t0mm13b
1
请查看这里...http://en.wikibooks.org/wiki/X86_Assembly/GAS_Syntax,以获取更多详细信息...这是我从上述链接学到的GAS基础知识... - t0mm13b
这不是GNU C内联asm(“template”:outputs:inputs:clobbers)从而访问C变量的方式,与MSVC不同,您不能仅在汇编代码中使用C var名称。https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html和https://stackoverflow.com/tags/inline-assembly/info。它也不适用于许多指令的AT&T语法,例如,AT&T对于内存操作数不使用方括号。https://stackoverflow.com/tags/att/info或查看GCC输出。并且,使用`movb`存储到`int`变量的低字节会使上3个字节保留未初始化的垃圾。 - Peter Cordes
GNU汇编器语法中的IN和OUT指令提供了一个示例,其中包含所需部分,但没有C变量输出。 - Peter Cordes

1
作为我的搜索结果,我会添加相关信息:
去看看 我可以使用Intel语法的x86汇编与GCC吗? GCC还有"-fverbose-asm"、"-fno-asynchronous-unwind-tables"和"-fconserve-stack",这些选项可能使生成的汇编代码更易于阅读。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接