Я пытаюсь создать высокоуровневый метод для вызова инструкции BTSTS.
Что я пробовал до сих пор:
volatile unsigned int a = 1;
asm volatile(
"btsts %0, #2\n"
: "+d" (b)
:
: "cc"
);
Выше выдает следующий сборочный вывод:
mov #1,w0
mov w0,[w14]
mov [w14],w0
mov w0,w1
btsts w1, #2
mov w1,w0
mov w0,[w14]
Но это не то, что я хочу. Бит должен быть установлен непосредственно в памяти, чтобы инструкция была атомарной:
btsts [w0], #2
Как правильно ее достичь?
Ближайший подход был следующий:
Здесь «а» - это глобальная переменная вместо локальной переменной
asm volatile(
"btsts [%0], #2\n"
:
: "d" (&a)
: "cc"
);
На этот раз генерируется следующий вывод сборки:
mov _a,w0
mov w0,w1
btsts [w1], #2
Это немного лучше, однако я не хочу явно указывать скобки [% 0] вокруг него. Разве нет способа, которым компилятор / ассемблер узнает, что требуется косвенная адресация памяти?
Редактировать: я попробовал еще одну вещь. Несмотря на то, что ограничение «m» не упоминалось в документации, я попробовал его
volatile unsigned int r = 0;
void test(volatile unsigned int* t) {
asm (
"btsts %0, #2\n"
: "+m" (t)
);
}
выше будет производить что-то вроде
mov #_r,w0
...
mov w0,[w14]
btsts [w14], #2
Это также неверно и не изменится r
. Может быть, ограничение "m" не упоминается, потому что оно глючит?
Btw. правильный код будет
btsts [w0], #2
или что-то вроде
mov w0,[w14]
mov [w14],w1
btsts [w1], #2