Outstripping the GCC Inline Compiler: inb/outb functions.
Posted: Thu Sep 11, 2003 9:16 pm
So, I got curious about how the GCC inline ASM compiler did so I had it compile two simple inline ASM functions: outportb and inportb. They look like this in C:
and
Basic enough. Then I disassembled them into their GNU ASM counterparts and tried to translate them. First, outportb. The disassembled code is pretty straight forward, as is the NASM translation next to it:
The code for the inportb function is quite different though, and I'd like to ask some questions. Here's the disassembled code:
(1) Flat out, why in the hell is this here? I could see if it was the addition of four to ESP, but not subtraction...
(2) This line and the next...doesn't that just simplify into mov edx, ax or xor edx, edx; mov dx, ax?
(3) Same problem with the last, doesn't this just expand al into the eax. (the same thing that would be achieved if you cleared eax right before the in call)?
Code: Select all
void outportb(unsigned port, unsigned val)
{
__asm__ __volatile__("outb %b0,%w1"
:
: "a"(val), "d"(port));
}
Code: Select all
unsigned inportb(unsigned short port)
{
unsigned char ret_val;
__asm__ __volatile__("inb %1,%0"
: "=a"(ret_val)
: "d"(port));
return ret_val;
}
Code: Select all
push %ebp push ebp
mov %esp, %ebp mov ebp, esp
mov 0x8(%ebp),%edx mov edx, [ebp + 8]
mov 0xc(%ebp),%eax mov eax, [ebp + 12]
out %al, (%dx) out dx, al
pop %ebp pop ebp
ret ret
Code: Select all
push %ebp
mov %esp, %ebp
sub $0x4,%esp <-------------------------(1)
mov 0x8(%ebp),%eax
mov %ax,0xfffffffe(%ebp) <------------(2)
movzwl 0xfffffffe(%ebp), %edx
in (%dx), %al
mov %al, 0xfffffffd(%ebp)<--------------(3)
movzbl 0xffffffd(%ebp),%eax
leave
ret
(2) This line and the next...doesn't that just simplify into mov edx, ax or xor edx, edx; mov dx, ax?
(3) Same problem with the last, doesn't this just expand al into the eax. (the same thing that would be achieved if you cleared eax right before the in call)?