• 0

GCC, inline assembly and constants


Question

I'm using some inline assembly using GCC (eew! AT&T syntax). I want to make use of constants defined in the C source within the assembly bock. However, ld is complaining when I link the binary. Consider the following (incomplete) example:

#define BAR	0

void foo() {
	asm("movl BAR, %eax\n");
}

Now, the error ld is giving me is that the symbol 'BAR' is undefined. BAR is a macro which I expect the preprocessor to inline. So does anyone know how I can use C constants (#defines) in inline assembly?

Link to comment
https://www.neowin.net/forum/topic/500582-gcc-inline-assembly-and-constants/
Share on other sites

8 answers to this question

Recommended Posts

  • 0

You can do something like this

#include <stdio.h>

#define BAR 2

int main( void ) {

		int foo;

		__asm__ __volatile__(
							 "movl %0, %%eax"
						   : "=r"(foo)	   // OUTPUT
						   : "r"(BAR)	   // INPUT
						   );

		printf("EAX=%d\n", foo);

		return 0;
}

This is how the program works:

1) The BAR is replaced by 2 at parsing

2) The 2 is stored in some register (Decided by the compiler for best optimization)

3) The first input argument %0 is moved into the eax register

4) Whatever is in eax is copied into foo

5) foo is printed in order to prove that eax is now 2.

  • 0
  dduardo said:

You can do something like this

#include <stdio.h>

#define BAR 2

int main( void ) {

		int foo;

		__asm__ __volatile__(
							 "movl %0, %%eax"
						   : "=r"(foo)	   // OUTPUT
						   : "r"(BAR)	   // INPUT
						   );

		printf("EAX=%d\n", foo);

		return 0;
}

This is how the program works:

1) The BAR is replaced by 2 at parsing

2) The 2 is stored in some register (Decided by the compiler for best optimization)

3) The first input argument %0 is moved into the eax register

4) Whatever is in eax is copied into foo

5) foo is printed in order to prove that eax is now 2.

Thanks for the reply. After half an hour of head banging on the table, I managed to figure it out. But I still don't understand why you can't just plug in a constant.

  • 0

The reason it doesn't work is because macros don't process stuff within double quotes

For example, lets say you have:

#define HELLO 15

but later in your code you have:

printf("HELLO = %d", HELLO);

Should the preprocessor change the line to:

printf("15 = %d", 15);

That doesn't make sense.

And I don't think there is a way to get around this behavior. If you do find a way I would like to know.

  • 0
  Andareed said:

You could do something like:

#define BAR	"0"

void foo() {
	asm("movl " BAR ", %eax\n");
}

I just tried it and it doesn't work. Sure it compiles, but then the program segfaults. When I disassembled the code in gdb you get a line like this:

mov 0x2,%eax

This is wrong. The line should be like this:

mov $0x2,%eax

To fix this the code should look like this:

#define BAR	"0"

void foo() {
	asm("movl $" BAR ", %eax\n");
}

This produces the correct assembly. Notice how there is a dollar sign after the movl.

Andareed, almost correct, but it needed a little tweaking.

  • 0
  Andareed said:

I was more commenting on a solution regarding C macros/inling problem that the op had. I'm unfamiliar with this style of asm - I typically work with masm/vc++ style asm.

Yeah, I'm also used to the Intel syntax that other, less sadistic assemblers use. But I decided to learn how GCC does it. It's kinda neat how GCC can do automatic register assignment with inline assembly. But the syntax is still not what I'm used to. Anywho, thanks, both of you, for your answers.

This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Posts

    • "We also highlighted that the Long-Term Servicing Channel (LTSC) version Windows 10 22H2 is also reaching end of support on that date." what? there is no LTSC version of Windows 10 22H2.
    • CrystalDiskInfo 9.7.1 by Razvan Serea CrystalDiskInfo is a HDD/SSD health monitoring utility. It displays basic HDD (also SSD and USB-HDD) information, monitors S.M.A.R.T. values and disk temperature. It will also display the S.M.A.R.T data as a list so you can see the specific issue that a hard drive may have. It provides a health rating based on your drive’s SMART status, plus will list its temperature, enabling you to see just how hot your drives are running. As various factors approach thresholds of danger, CrystalDiskInfo will alert you, letting you know it's time to make backups while you still can. CrystalDiskInfo 9.7.1 changelog: Fixed the problem that some SATA SSDs misjudged the remaining life as 0%. Improved support for aigo PSSD P6 Improved support for Lexar SSD Improved support for SanDisk SSDs Updated language file (Traditional Chinese, Korean, Dutch) Download: CrystalDiskInfo 9.7.1 | 5.8 MB (Open Source) Download: Portable CrystalDiskInfo 9.7.1 | 7.8 MB View: CrystalDiskInfo Home Page | Screenshot Get alerted to all of our Software updates on Twitter at @NeowinSoftware
    • Zen Browser 1.14.8b is out.
    • There are numerous Linux distros that are actually geared more to beginners and less tech savvy users. Take advantage of the fact we have different Linux distros that target certain kinds of users.
    • Because that is who Neowin uses.
  • Recent Achievements

    • First Post
      smileyhead earned a badge
      First Post
    • One Month Later
      K V earned a badge
      One Month Later
    • Week One Done
      K V earned a badge
      Week One Done
    • Dedicated
      CarlosABC earned a badge
      Dedicated
    • One Month Later
      solidox earned a badge
      One Month Later
  • Popular Contributors

    1. 1
      +primortal
      639
    2. 2
      ATLien_0
      241
    3. 3
      Xenon
      174
    4. 4
      neufuse
      155
    5. 5
      +FloatingFatMan
      123
  • Tell a friend

    Love Neowin? Tell a friend!