2

This code print "Hello World!" and exit without C library. ref.(Programmer's self-cultivation -- Link, load, and library)

I do not understand why there is "%%" in front of "rax" in print(), but "%" in front of "rax" in exit(). I have tried to add another "%" in front of "rax" in exit(), and I get the error message:

TinyHelloWorld.c:14: Error: bad register name `%%rbx'
TinyHelloWorld.c:15: Error: bad register name `%%rax'

WRITE has a system call number of 4 and EXIT is 1, I have no idea what is the difference about the use of "rax"?

char *str="Hello world!\n";

void print()
{
    asm("movq $13,%%rdx \n\t"
        "movq %0,%%rcx \n\t"
        "movq $0,%%rbx \n\t"
        "movq $4,%%rax \n\t"
        "int $0x80     \n\t"
        ::"r"(str):"edx","ecx","ebx");
}

void exit()
{
   asm("movq $42,%rbx   \n\t"
       "movq $1,%rax    \n\t"
       "int $0x80       \n\t");
}

void nomain()
{
   print();
   exit();
}
Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
M xie
  • 31
  • 2
  • 1
    Here "%%" maybe an escape character for format string. – Geno Chen Dec 26 '18 at 14:22
  • 2 unsafe things here: `"r"(str)` input constraint doesn't tell the compiler the pointed-to memory is also an input. A dummy memory operand would be better. Also, the `int 0x80` 32-bit ABI doesn't work for 64-bit pointers, so this will fail if you build make a PIE executable. [What happens if you use the 32-bit int 0x80 Linux ABI in 64-bit code?](https://stackoverflow.com/q/46087730). Also inefficient: you can simply ask for inputs in the right registers, instead of using `mov` inside the asm, with `"a"(4), "d"(strlen(str)), ...`. Let the compiler do everything but `syscall` or `int`. – Peter Cordes Dec 26 '18 at 16:38
  • See https://stackoverflow.com/tags/inline-assembly/info for links to docs and guides. – Peter Cordes Dec 26 '18 at 16:38

1 Answers1

4

The first block uses "extended asm", the second "basic asm". In basic asm the single % prefix is used like in a standalone assembly source code: to determine a register. In extended asm the % prefix is used to identify one of the additional operators (InputOperands, OutputOperands, Clobbers, GotoLabels). To preserve the % prefix of the registers, you have to double it. This is called a special format string.

Informative: How to Convert Basic asm to Extended asm

rkhb
  • 14,159
  • 7
  • 32
  • 60