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
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.
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.
Unsurprisingly, Assembly is crowned the most difficult language to learn on a beginner level followed by Haskell.
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]
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").
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With