I am writing an inline assembly code to read Real-Time clock. I am loading the register number(4) to be read to 'dl' and loading this to port 0x70. I am trying to read this register value(4) into al. For more information - RTC
asm(
"mov $4, %%dl;"
"out 0x70, %%dl;"
"in %%al, 0x71;"
:
:
:"%al","%dl"
);
I am getting the below error message on compiling the c file that contains this code.
Assembler messages:
Error: operand size mismatch for 'out'
Error: operand size mismatch for `in'
The assembler version : GNU assembler version 2.26.1 (x86_64-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.26.1
Can someone please point out the issue?
There are a number of problems. First, both
in
andout
can only operate on the A register (al
,ax
,eax
,rax
). Second, the operand order is wrong and third, immediates have to be prefixed with$
in AT&T syntax. In plain assembly, your code should look like this:So your corrected assembly would be
Note that I have added explicit size suffixes to help clang assemble this code. I recommend you to further alter this code to use correct extended inline assembly:
This could make gcc generate slightly better code. For example, it allows gcc to inline this code.
Furthermore, you could consider using the
inb()
andoutb()
macros from<sys/io.h>
to avoid inline assembly altogether. This is typically a very good thing to do.