3

I want to know if there is a way of calling in a .c assembly code? I want to put this code in my .c file

The assembly code i want to execute in .c file to return the address

1. mov eax, 0x2d
2. mov ebx, 0
3. int 0x80

I know the answer is put eax.

This is the part of .c file:

1. void function(void)
2. {
3. void *sp;
4. sp = eax;
5. fprintf(stderr, "system break:   %p\n", sp);
6. }

How can I do it?

Weigel Gram
  • 185
  • 1
  • 2
  • 11
  • Which C compiler are you using? – ct_ Nov 03 '12 at 08:36
  • What is the C code supposed to do, what value is in eax, what is sp? – hyde Nov 03 '12 at 09:04
  • @hyde I'm using gcc and sp is just a variable, and want to do this,fprintf(stderr, "system break: %p\n", sp); when i have sp, and sp has eax value, the value in eax is something like 0x99ae000 – Weigel Gram Nov 03 '12 at 09:22

5 Answers5

9

The ability to do this is compiler-specific. Gcc allows this using its asm keyword extension, while Visual studio implements a different extension.

Note that, beside the obvious problem with non-portability to other architectures, including any inline assembly can reduce performance because the compiler is unable to analyze the assembly to determine whether it's side-effect-free, safe for inlining, whether it accesses global resources, and so on.

user4815162342
  • 141,790
  • 18
  • 296
  • 355
  • I'm not worried about performance at the moment, just a print out. so i can just say asm ("code stuff"); in my .c file – Weigel Gram Nov 03 '12 at 09:28
  • http://www.codeproject.com/Articles/15971/Using-Inline-Assembly-in-C-C, I think this site is a better example – Weigel Gram Nov 04 '12 at 21:18
  • 1
    and with this "http://stackoverflow.com/questions/5131568/using-inline-assembly-in-c-c" i think everything i wanted to know about inline assembly i konw now. – Weigel Gram Nov 04 '12 at 21:21
4

Some compilers implement the __asm__ or asm keywords as an extension to the C language:

__asm__(
    "mov eax, 0x2d\n"
    "mov ebx, 0\n"
    "int 0x80\n"
);

The code in parentheses will be copied verbatim to the input of the assembler. More documentation of how, for example, GCC implements this feature, can be found here.

By the way, if you want to alter the value of the stack pointer (why?), you can do it in one line:

__asm__("mov esp, eax");
  • I think sp is just C variable name here, nothing to do with stack pointer. – hyde Nov 03 '12 at 09:02
  • @hyde Quite possible :) However, when the context is "inline assembly", and "void *sp = eax;", then forgive me for this assumption :) –  Nov 03 '12 at 09:03
  • How can i now call that fuction and so that sp = the return? sp = asm("asm code"); ??? – Weigel Gram Nov 03 '12 at 09:33
  • @WeigelGram No, but if you had read the document at the link I provided, you would know that. –  Nov 03 '12 at 09:37
  • @H2CO3 How can I now call that fuction and so that sp = the value of eax? void *sp; asm("mov eax,0x2222": output operands :input operands ); ??? what do i need at output operands or input operands so that when i say: fprintf(stderr, "system break: %p\n", sp); ouput system break 0x2222 – Weigel Gram Nov 03 '12 at 09:53
  • It confuses me a little bit at the examples – Weigel Gram Nov 03 '12 at 09:54
  • 1
    @WeigelGram I believe you have to write `__asm("mov %%eax, 0x222" : "+r"(sp));` –  Nov 03 '12 at 09:58
  • Never use GNU C Basic asm inside a function (except as the body of a `naked` function). You need inputs / outputs / clobbers to be able to use registers, and affect C variables. Also, this is using Intel syntax so it requires `-masm=intel`. – Peter Cordes Mar 23 '21 at 21:14
3

Another method if e.g. using gcc, is to first compile some very trivial function without optimizations:

int foo(int a, int b) {
  return a+(b<<3);
}

with gcc -S foo.c

and use the foo.s as template. One can later compile and link those files with gcc main.c foo.s (and be sure to delete the foo.c file / rename foo.s to something else)

From that particular function one can observe, where the compiler puts the result and in which addresses or registers the compiler puts the first and second arguments.

It's slightly faster approach than learning asm-templates with read,write, clobber lists.

Aki Suihkonen
  • 19,144
  • 1
  • 36
  • 57
2

You really need to "put" asm source in Nasm syntax "in" your C source program? Fergedit. lcc maybe... If you want to "execute" your asm program from your C program...

    global getbrk
    section .text
    getbrk:
        push ebx ; C likes it saved
        mov eax, 45 ; __NR_brk
        xor ebx, ebx ; get current break
        int 80h
        pop ebx
        ret

assemble nasm -f elf getbrk.asm, put sp=getbrk(); in your C file, compile gcc -m32 -O3 -o myprog myprog.c getbrk.o

Or just sp=sbrk(0); in your C program and skip the asm... won't be any more portable than doing it with int 80h. (but what fun would that be?) :)

Community
  • 1
  • 1
Frank Kotler
  • 1,462
  • 1
  • 8
  • 4
  • The hole point to my problem was that I did not/or may not use sp = sbrk(0) in my c program; but thanks anyway. And I think your solution would have worked also. – Weigel Gram Nov 06 '12 at 20:46
2
void function(void){

   void *sp
   __asm__ volatile(
   "movl $0x2d, %%eax;"
   "movl $0, %%ebx;"
   "int $0x80"
   :"=a"(sp)
   :
   :"%ebx"
   );

   fprintf(stderr, "system break: %p\n",sp);
   }

This is my answer :)

Weigel Gram
  • 185
  • 1
  • 2
  • 11
  • You'd normally want to use input constraints to get the compiler to set up the right values in registers around a `"int $0x80"` template, but yes this is safe. With some system calls you'd want a `"memory"` clobber, but this one doesn't pass any pointers so there's no need for memory to be in sync. Anyway, `asm volatile("int $0x80" : "=a"(sp) : "a"(__NR_brk), "b"(0));` would be a good option. – Peter Cordes Mar 23 '21 at 21:12
  • See also https://stackoverflow.com/tags/inline-assembly/info – Peter Cordes Mar 23 '21 at 21:14