Встроенный ASM Arduino работает не так, как ожидалось

Я пытаюсь построить часы, поэтому я работаю с ASM и Arduino. Для большинства частей подойдет обычный C, но для подготовки времени к выводу в преобразователи BCD в десятичные числа я решил использовать ASM. Я написал следующий код в 8086 C ++ / ASM, и он отлично работает на моем компьютере:

#include <iostream>

using namespace std;

int main(int argc, char **argv)
{
for(int num = 0; num < 16; num++) {
int bin[4];
bin[0] = bin[1] = bin[2] = bin[3] = 0;
asm("movl %%ebx, %%eax;""andl $8, %%eax;""cmp $0, %%eax;""je a;""movl $1, %0;""jmp b;""a: movl $0, %0;""b: movl %%ebx, %%eax;""andl $4, %%eax;""cmp $0, %%eax;""je c;""movl $1, %1;""jmp d;""c: movl $0, %1;""d: movl %%ebx, %%eax;""andl $2, %%eax;""cmp $0, %%eax;""je e;""movl $1, %2;""jmp f;""e: movl $0, %2;""f: movl %%ebx, %%eax;""andl $1, %%eax;""cmp $0, %%eax;""je g;""movl $1, %3;""jmp h;""g: movl $0, %3;""h: nop": "=r" (bin[0]), "=r" (bin[1]), "=r" (bin[2]), "=b" (bin[3])
: "b" (num)
: "%eax");
cout << num << ": ";
for(int i = 0; i < 4; i++) {
cout << bin[i];
}
cout << endl;
}
return 0;
}

Однако, когда я изменил его для запуска на Arduino, все перестало работать полностью:

  for(uint8_t num = 0; num < 16; num++) {
uint8_t bin[4];
bin[0] = bin[1] = bin[2] = bin[3] = 0;
asm("mov __tmp_reg__, %[val];""and __tmp_reg__, $8;""cmp __tmp_reg__, $0;""je a;""mov %[bit8], $1;""rjmp b;""a: mov $0, %[bit8];""b: mov %[val], __tmp_reg__;""and __tmp_reg__, $4;""cmp __tmp_reg__, $0;""je c;""mov %[bit4], $1;""rjmp d;""c: mov $0, %[bit4];""d: mov %[val], __tmp_reg__;""and __tmp_reg__, $2;""cmp __tmp_reg__, $0;""je e;""mov %[bit2], $1;""rjmp f;""e: mov $0, %[bit2];""f: mov %[val], __tmp_reg__;""and __tmp_reg__, $1;""cmp __tmp_reg__, $0;""je g;""mov %[bit1], $1;""rjmp h;""g: mov $0, %[bit1];""h: nop": [bit8] "=r" (bin[0]), [bit4] "=r" (bin[1]), [bit2] "=r" (bin[2]), [bit1] "=r" (bin[3])
: [val] "r" (num)
: "r0");

Код 8086 дает ожидаемый результат:

0: 0000
1: 0001
2: 0010
3: 0011

13: 1101
14: 1110
15: 1111

Но код, запускаемый на Arduino, дает другой результат:

0: 5000
1: 0000
2: 0000
3: 0000
… (нули продолжаются)
13: 0000
14: 0000
15: 0000

Как вы можете себе представить, код становится бесполезным, если он возвращает … пять. И я не знаю, как он может вернуть 5, когда в источнике нет ничего близкого к 5. Я в растерянности относительно того, что делать здесь, поэтому я действительно мог бы использовать некоторую помощь.

Я использую Arduino Leonardo, который имеет процессор ATMega32U. Я пытался разобрать исполняемый файл, сгенерированный программным обеспечением Arduino (которое компилирует его с помощью AVR-GCC), но, похоже, я ничего не могу найти в моих попытках найти код, который я вставил.

Спасибо за ваше время, переполнение стека.

1

Решение

Код, который вы имеете, может быть легко написан на C ++, например:

 int bin[4] = {};

bin[0] = !!(num & 8);
bin[1] = !!(num & 4);
bin[2] = !!(num & 2);
bin[3] = !!(num & 1);

или же:

int bin[4];
int bit = 8;
for(int i = 0; i < 4; i++)
{
bin[i] = !!(num & bit);
bit >>= 1;
}

Если тебе не нравится !! (что заставляет «принять следующее значение и сделать его либо 0 [если оно ложно], либо 1 [если оно истинно]), вы можете заменить его на:

for(int i = 0; i < 4; i++)
{
bin[i] = (num >> 3 - i) & 1;
}

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

1

Другие решения

Других решений пока нет …