ARMv7 Assembly Language: как добавить два uint32_t и вернуть результат uint64_t - PullRequest
0 голосов
/ 01 марта 2019

Я новичок в освоении программирования на языке ассемблера ARM7, и я застрял в этой одной проблеме.

Я пытаюсь реализовать функцию в C, которая принимает два 32-разрядных переменной без знака (uint32_t A и uint32_t B).), складывает их вместе, а затем возвращает значение uint64_t, в котором сумма содержит перенос.

Я включил ниже мой код C и код языка сборки ARM7.Однако мой код не выводит правильное значение;что, вероятно, из-за моих инструкций ASM.Кроме того, я использую Linux на 32-битной машине.

addVal.s (код ниже)

.global addVal 

.text

addVal:
    ADD R0, R0, R1
    ADC R0, R1 
    BX LR

addVal.c (код ниже)

#include <stdio.h>
#include <stdint.h>

extern uint64_t addVal(uint32_t x, uint32_t y);

int main()
{
  uint32_t a, b;
  uint64_t c;
  a = 4000000000;
  b = 1000000000;
  c = addVal(a,b);
  printf("a = %u\r\n", a);
  printf("b = %u\r\n", b);
  printf("c = a + b = %llu\r\n", c);
  return 0;

}

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

as -o addVal addVal.o addVal.s
gcc -o addVal addVal_s.o addVal.c
./addVal

1 Ответ

0 голосов
/ 01 марта 2019

ADC R0, R1 неверно.

Поскольку uint64_t превышает размер одного регистра, он распространяется на последующий диапазон регистров.Младшее слово находится в R0, старшее слово в R1.Таким образом, целевой регистр для ADC должен быть R1.

Вторая проблема заключается в том, что вы не хотите добавлять исходное младшее слово R1 в результирующее старшее слово, а только переноситьнемного.Так что сначала вы можете очистить R1.

.text
.arm
.global addVal 
.func addVal
addVal:
    ADDS R0, R0, R1
    MOV R1, #0
    ADC R1, R1, #0
    BX LR
...