unsigned int stuff[10];
void fun ( void )
{
unsigned int r;
for(r=0;r<10;r++) stuff[r]=r;
}
с использованием ARM ...
00000000 <fun>:
0: e3a03000 mov r3, #0
4: e59f2010 ldr r2, [pc, #16] ; 1c <fun+0x1c>
8: e5a23004 str r3, [r2, #4]!
c: e2833001 add r3, r3, #1
10: e353000a cmp r3, #10
14: 1afffffb bne 8 <fun+0x8>
18: e12fff1e bx lr
1c: 00000ffc
Disassembly of section .bss:
00001000 <stuff>:
...
Массив - это просто данные, это не код, это не инструкции и не будет, директива, о которой вы спрашивали, не будет становитесь кодом, он не может быть данными.
Если вы хотите увидеть код, инструкции, то вам нужно поместить строки языка высокого уровня, которые воздействуют на данные, например, как показано здесь. И в этом случае компилятор генерирует код.
Глядя на фактический вывод этого компилятора (комментарии и другие несущественные элементы удалены)
fun:
mov r3, #0
ldr r2, .L6
.L2:
str r3, [r2, #4]!
add r3, r3, #1
cmp r3, #10
bne .L2
bx lr
.L7:
.align 2
.L6:
.word stuff-4
...
.comm stuff,40,4
.comm в этом случае - это то, как они объявили данные, которые представляют массив на языке высокого уровня. а другие вещи в основном код. .align существует для того, чтобы адрес L6 был выровнен, так что вы не получите ошибку выравнивания при попытке прочитать его.
.word - это директива, здесь вы видите .text vs .data, в то время как это всего лишь одна простая C программа с массивом и кодом прямо рядом друг с другом. потому что код, возможно, может жить в памяти только для чтения, такой как fla sh, а данные должны находиться в памяти чтения / записи, и во время компиляции компилятор не знает, где находятся данные относительно кода, поэтому он генерирует абстракцию, помещая слово только для чтения в коде, который компоновщик заполняет позже, код является обобщенным c и что бы там ни вставлял компоновщик, он использует его. Компоновщик "помещает" .text и .bss в этом случае он не был инициализирован, поэтому он фактически не является .data, а затем устанавливает это соединение в коде.
метки являются директивами, если хотите, чтобы программист или генератор кода (компилятор) не должен считать инструкции или общий размер инструкций, чтобы сделать относительные переходы. Пусть инструменты сделают это за вас.
1c: 00000ffc
Disassembly of section .bss:
00001000 <stuff>:
...
и, исходя из того, как я связал эту (не фактически работающую) программу, это единственный элемент данных в этой программе, и компоновщик разместил его там, где я спросил адрес 0x1000, затем вернулся и заполнил эту директиву .word, чтобы она была stuff-4, которая равна 0xFF C, так что код скомпилированный работает. Директивы
не являются частью набора команд, но являются частью обратите внимание, что язык ассемблера определяется ассемблером, инструментом, а не набором команд / целью. Существует бесчисленное множество различных языков ассемблера x86, и AT & T против Intel не является основным отличием: директивы, как вы определяете метку, как вы указываете число шестнадцатеричное или десятичное, из-за нечеткости инструкций, как определено в ранних документах. прилагательные, если вы хотите иметь возможность указать, какую инструкцию mov вы на самом деле выполняли, и даже если это часть инструкции, а не директива, эти прилагательные различаются в разных языках ассемблера. В ARM, MIPS и многих, если не в большинстве других, были созданы инструменты с несовместимыми языками ассемблера. Например, .zero является одной из этих несовместимых вещей.
В любом случае рассматриваемый язык ассемблера должен иметь возможность определять данные, а затем иметь способ для кода ссылаться на эти данные для создания полезных программ.
Понятие языка ассемблера с инструкциями один к одному очень вводит в заблуждение, и его не обмануть, современные компиляторы генерируют почти столько же кода, сколько и кода в выходных данных. Много директив и другой информации.