3

I was toying around with GCC assembly output a little, trying it with a fast integer average. Here's the C code I used initially:

unsigned int average (unsigned int x, unsigned int y) {
    return (x&y)+((x^y)>>1);
}

Here's the assembly it emitted (using Intel syntax):

average:
  mov edx, edi
  and edi, esi
  xor edx, esi
  shr edx
  lea eax, [rdx+rdi]
  ret

When I translated it for NASM:

average:
    mov edx, edi
    and edi, esi
    xor edx, esi
    shr edx, 1
    lea eax, [rdx+rdi]
    ret

It complains with this error, on the line with lea:

<source>:6: error: impossible combination of address sizes
<source>:6: error: invalid effective address

I'm not super familiar with assembly, but this seems super odd. Could someone explain to me what the heck is going on here?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Claudia
  • 1,197
  • 15
  • 30
  • Has other output when translated/plugged into NASM from GCC output worked? – whatthefish Jun 06 '18 at 19:44
  • In my experience, it usually has, but not 100% of the time. I'm just curious what specifically makes *this* example not work. – Claudia Jun 06 '18 at 20:02
  • I updated the question name and tags to clarify I'm asking about a failed code translation, not a simple plugging output to input. – Claudia Jun 06 '18 at 20:05

1 Answers1

8

The error message is misleading. The cause of this error is that nasm tries to assemble your code as 16 or 32 bit code, both of which do not support 64 bit registers. To fix this problem, invoke nasm with options that cause it to assemble 64 bit code, e.g. on Linux:

nasm -f elf64 source.asm

or on Windows:

nasm -f win64 source.asm
fuz
  • 88,405
  • 25
  • 200
  • 352