在c中理解汇编代码

ZLW*_*ZLW 7 c assembly clang

我正在阅读一些嵌入了一些汇编代码的C代码.我理解这__asm__是一个运行汇编代码的语句,但是__asm__在下面的代码中做了什么?根据输出(即r = 16),似乎__asm__不影响变量r.不是吗?

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

    printf("foo: %u\n", r);
}
Run Code Online (Sandbox Code Playgroud)

平台:OSX Yosemite上的Apple LLVM 6.0版(clang-600.0.56)(基于LLVM 3.5svn)

pau*_*sm4 4

严格来说,您的“asm”片段只是加载一个常量(0x0019)。

这是一个 32 位示例:

#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
Run Code Online (Sandbox Code Playgroud)

PS:“asm”语法适用于所有基于 gcc 的编译器。

PPS:我绝对鼓励您在任何您喜欢的地方尝试汇编:嵌入式系统、Ubuntu、Mac OSX - 无论您喜欢什么。

这是一本很棒的书。它是关于 Linux 的,但它也很大程度上适用于您的 OSX:

从头开始编程,乔纳森·巴特利特

还:

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

http://fabiensanglad.net/macosxassemble/

PPS:x86 汇编语法有两种变体:“Intel”和“ATT”语法。Gcc 使用 ATT。ATT 语法也适用于 GCC 支持的任何其他架构(MIPS、PPC 等)。我鼓励您从 ATT 语法(“gcc/gas”)开始,而不是 Intel(“nasm”)。