5

I know this is a very basic question but I am really stuck on it. In fact I am absolutely newbie in GCC syntax.

I want to have local variables (Stack addresses with labels) without using extended inline assembly. Something like the following code in Intel syntax:

DATA1  DB  100 
MOV AL, DATA1

This is the code I guess may substitute in GCC:

int someFunction(int x)
{
    __asm__ volatile(
                     "function1:"
                     ".data;"
                     ".2byte $4 data1   ;"

                     ".text;"
                     "pushq %rbp;"
                     "movq %rsp , %rbp ;"

                     "movl var , %eax;"  // this is source of error

                     "popq %rbp;"
                     "leaveq;"
                     "retq ; "
                    ); 
}

But this code results in this error:

symbol(s) not found for architecture x86_64

I can use global variables in x86 but the same result comes in x64 or x86_x64.

Setting: LLVM 4.1; Cocoa used in Xcode 4

What is the correct syntax?

istepaniuk
  • 4,016
  • 2
  • 32
  • 60
Aug
  • 595
  • 9
  • 22
  • Note that `DATA1 DB 100` is static storage. Like `static char DATA1 = 100;` non-`static` Local variables (automatic storage class) live in registers, or on the stack if you run out of registers or need to take their address. So the same function can be running in multiple threads without stepping on itself: it's re-entrant. – Peter Cordes Jun 14 '19 at 11:35

1 Answers1

7

GCC inline assembler doesn't support local variables, use GCC's extended syntax.

If you are uncomfortable with AT&T syntax there are ways to use Intel syntax on GCC.

This is an excellent how-to on GCC asm.

istepaniuk
  • 4,016
  • 2
  • 32
  • 60
  • But how do you know where the variable is on the stack to begin with? Do you just assume gcc creates a new stack frame at the beginning and assume the first local variable is right above that or what? – greatwolf Nov 14 '13 at 11:01
  • 1
    @greatwolf: no, that suggestion is total garbage. **Don't try to hard-code how gcc does stack layout**. Even if you do know where it is relative to the stack pointer, the compiler will assume you haven't modified it. You *must* use Extended inline asm with an input/output operand to read, write, or read+write local variables *safely*. Unless you like writing code that only works in an un-optimized debug build with a specific version of gcc and will still break as soon as you change the surrounding code. – Peter Cordes Jun 13 '19 at 15:09
  • @PeterCordes thanks, I was probably thinking aloud there, I will remove that bit from the answer – istepaniuk Jun 14 '19 at 10:28
  • Also related: https://gcc.gnu.org/wiki/ConvertBasicAsmToExtended - you should *never* use Basic asm inside a function. Only at global scope, or in a `__attribute__((naked))` function, where you can't use C statements or Extended asm, and you write the entire function body including the `ret`, and handle the calling convention yourself. It's technically safe to do `asm("lfence")` or something that doesn't affect memory or registers, but usually you want to know that it's ordered wrt. memory access and stuff in the surrounding C. – Peter Cordes Dec 18 '20 at 05:57
  • And BTW, `asm("movl $123, global_var")` isn't safe: it doesn't tell the compiler you modify that memory. It will compile and assemble without error, but it's still unsafe and will break. [How can I indicate that the memory \*pointed\* to by an inline ASM argument may be used?](https://stackoverflow.com/q/56432259) – Peter Cordes Dec 18 '20 at 05:58