Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understand assembly code in c

Tags:

c

assembly

clang

I'm reading some C code embedded with a few assembly code. I understand that __asm__ is a statement to run assembly code, but what does __asm__ do in the following code? According to the output (i.e., r = 16), it seems that __asm__ does not effect the variable r. Isn't it?

#include <stdio.h>
static void foo()
{
    static volatile unsigned int r __asm__ ("0x0019");
    r |= 1 << 4;

    printf("foo: %u\n", r);
}

Platform: Apple LLVM version 6.0 (clang-600.0.56) (based on LLVM 3.5svn) on OSX Yosemite

like image 220
ZLW Avatar asked Dec 27 '14 20:12

ZLW


People also ask

What is assembly code in C?

Assembly Language mainly consists of mnemonic processor instructions or data and other statements or instructions. It is produced with the help of compiling the high-level language source code like C, C++. Assembly Language helps in fine-tuning the program.

Can you run assembly code in C?

We can write assembly program code inside c language program. In such case, all the assembly code must be placed inside asm{} block. Let's see a simple assembly program code to add two numbers in c program.

Is assembly code easy to learn?

Unsurprisingly, Assembly is crowned the most difficult language to learn on a beginner level followed by Haskell.

What is assembly code with example?

An assembly language statement is a line of text that translates into a single machine instruction. Assembly Language is expressed in a more human readable form than the binary instructions and names are allowed for memory locations, registers, operations etc. For example: ADD [result],[coursework],[exam]


1 Answers

Strictly speaking, your "asm" snippet simply loads a constant (0x0019).

Here's a 32-bit example:

#include <stdio.h>
static void foo()
{
    static volatile unsigned int r __asm__ ("0x0019");
    static volatile unsigned int s __asm__ ("0x1122");
    static volatile unsigned int t = 0x3344;
    printf("foo: %u %u %u\n", r, s, t);
}

gcc -O0 -S x.c

cat x.c
        .file   "x.c"
        .data
        .align 4
        .type   t.1781, @object
        .size   t.1781, 4
t.1781:
        .long   13124  # Note: 13124 decimal == 0x3344 hex
        .local  0x1122
        .comm   0x1122,4,4
        .local  0x0019
        .comm   0x0019,4,4
        .section        .rodata
.LC0:
        .string "foo: %u %u %u\n"
        .text
        .type   foo, @function
foo:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $24, %esp
        movl    t.1781, %eax
        movl    0x1122, %edx
        movl    0x0019, %ecx
        movl    %eax, 12(%esp)
        movl    %edx, 8(%esp)
        movl    %ecx, 4(%esp)
        movl    $.LC0, (%esp)
        call    printf
        leave
        ret

PS: The "asm" syntax is applicable to all gcc-based compilers.

PPS: I absolutely encourage you to experiment with assembly anywhere you please: embedded systems, Ubuntu, Mac OSX - whatever pleases you.

Here is an excellent book. It's about Linux, but it's also very largely applicable to your OSX:

Programming from the Ground Up, Jonathan Bartlett

Also:

https://www.hackerschool.com/blog/7-understanding-c-by-learning-assembly

http://fabiensanglard.net/macosxassembly/

PPS: x86 assembly syntax comes in two variants: "Intel" and "ATT" syntax. Gcc uses ATT. The ATT syntax is also applicable for any other architecture supported by GCC (MIPS, PPC, etc etc). I encourage you to start off with ATT syntax ("gcc/gas"), rather than Intel ("nasm").

like image 162
FoggyDay Avatar answered Sep 28 '22 21:09

FoggyDay