Сборка ARM - добавление двух регистров - PullRequest
1 голос
/ 09 февраля 2020

Я пытаюсь добавить два регистра вместе в сборке ARM, разыменовав первые два регистра, а затем сохранив результат в третьем регистре.

На данный момент у меня есть 3 переменные и функция, которые следующие:

extern void my_function(int* x, int* y, int* total);

int main(void){
   int x = 1;     //R0
   int y = 2;     //R1
   int total = 0; //R2

   while(1){
      my_function(&x, &y, &total);
      printf("\x1b[5;5HTotal = %d, total");
   }
}

И функция, которая выполняет следующее

С первыми двумя регистрами, Я пытаюсь разыменовать их, сложить вместе и сохранить результат в третьем регистре. Это мой ассемблерный код;

ldr r4, [r0]    @ Dereference r0, and store the address in R4
ldr r4, [r1]    @ Dereference r1, and store the address in R4
add r2, r0, r1  @ Add r0 & r1 together, and store in R2
str r4, [r2]    @ Store r2 address in r4

Когда я распечатываю это, ответ равен 0. Мой вопрос: когда я делаю первые две строки в сборке, заменяется ли ldr r4, [r0] на ldr r4, [r1] что является причиной выхода на 0? Каждый из них должен храниться в своем собственном реестре? Или я просто распечатываю итоги (r2)?

1 Ответ

2 голосов
/ 09 февраля 2020

Никогда не запускайте проект на языке ассемблера без документации. Затем фактически прочитайте эту документацию.

У вас есть C компилятор, так что вы можете просто посмотреть, что он делает, а затем выяснить, что делает каждая инструкция, а затем выяснить, где вы ошиблись.

void my_function(int* x, int* y, int* total)
{
    *total = *x + *y;
}

может выдавать в зависимости от параметров командной строки

my_function:
    ldr r3, [r0]
    ldr r1, [r1]
    add r3, r3, r1
    str r3, [r2]
    bx  lr

вы также должны понимать соглашение о вызовах для компилятора, который вы используете для перехода C / asm. для этого случая в ответвлении r0 указан адрес x, r1 - адрес y, а r2 - адрес итога.

ldr r4, [r0]    @ read the value of x into r4
ldr r4, [r1]    @ read the value of y into r4 losing/discarding the value of x
add r2, r0, r1  @ add the pointers together destroying the pointer to total
str r4, [r2]    @ store the value of y into a location destroying whatever was there

в соответствии с типичным соглашением о вызовах (компилятор может использовать / создавать все, что он хочет, поэтому вам нужно знать соглашение) для arm r4 изменчиво, поэтому вам нужно положить sh на в стеке, вы не можете уничтожить то, что находится в ней во время вашей функции.

, потому что ваша программа не изменяет переменную итогов и является частью .bss * bootstrap имеет обнуленное общее значение до нуля, и вы просто печатаете из этого значения, поэтому вы видите ноль, ваш код не имеет ничего общего с ним. Шансы на адрес x плюс адрес y, являющийся адресом total, очень очень малы, практически нулевые (хотя программа может быть создана там, где она работает), поэтому ваш код опять не имеет ничего общего с нулевым значением в общем .

...