2014-12-27 3 views
7

Я читаю некоторый код кода, встроенный в несколько ассемблерных кодов. Я понимаю, что __asm__ - это инструкция для запуска кода сборки, но что делает __asm__ в следующем коде? В соответствии с выходом (то есть r = 16), кажется, что __asm__ не влияет на переменную r. Не так ли?Понять код сборки в c

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

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

Платформа: Apple LLVM версии 6.0 (лязг-600.0.56) (на основе LLVM 3.5svn) на OSX Yosemite

+2

Какой компилятор и платформа? – interjay

+0

Apple LLVM version 6.0 (clang-600.0.56) (на основе LLVM 3.5svn) на OSX Yosemite – Zilong

+1

Это может означать, что 'r' является значением слова памяти адреса' 0x0019' –

ответ

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 

PS: Синтаксис "ASM" применим ко всем GCC на основе компиляторов.

PPS: Я абсолютно рекомендуем вам поэкспериментировать с узлом где-нибудь пожалуйста: встроенные системы, Ubuntu, Mac OSX - все, что вам угодно.

Вот отличная книга. Речь идет о Linux, но также в значительной степени применимо к вашему OSX:

Programming from the Ground Up, Jonathan Bartlett

Также:

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

http://fabiensanglard.net/macosxassembly/

PPS: x86 синтаксис сборки поставляется в двух вариантах: Синтаксис «Intel» и «ATT». Gcc использует ATT. Синтаксис ATT также применим для любой другой архитектуры, поддерживаемой GCC (MIPS, PPC и т. Д. И т. Д.). Я рекомендую вам начать с синтаксиса ATT («gcc/gas»), а не Intel («nasm»).

+0

Большое спасибо. Но я до сих пор не понимаю, почему gcc не смог скомпилировать его в исполняемый файл, в то время как clang мог. Я прочитаю ваши предлагаемые статьи и попытаюсь понять код сборки, который был создан. – Zilong

+0

Привет - Рад, что это помогло. Что бы это ни стоило, я на самом деле скомпилировал фрагмент выше (вырезанный/вставленный из вашего кода) в двух версиях GCC: 32-битных Centos 5.5 и 64-bit CentOS 6.4. Он скомпилирован («собран»;)) отлично, но я не пытался связывать или исполнять любую версию. – FoggyDay

Смежные вопросы