gpt4 book ai didi

c - 需要未移位的寄存器 - 汇编器在 TST 指令上抛出错误

转载 作者:行者123 更新时间:2023-12-05 02:30:24 26 4
gpt4 key购买 nike

我目前正在将算法从 C 语言重写到 arm 汇编语言(ARM Cortex M4 CPU)。

我的代码有什么作用?

该算法将一个 8 位数字作为输入,并从右边开始告诉我们第一个为 0 的位是什么。下面是几个例子:

输入:B01111111 输出:7

输入:B01110111 输出:3

输入:B11111110 输出:0

这是完成此操作的原始 C 代码:

uint8_t find_empty(uint32_t input_word)
{
for (uint8_t searches=7; searches>=0; searches--)
{
if ((input_word&1)==0)
{
return 7-searches;
}

input_word=input_word>>1;
}
return 255;
}

这是我在 ARM (Cortex M4) 程序集中重写它的初学者尝试。

.global findEmpty
findEmpty:
mov r1, r0 //Move input_word to r1

//Config
mov r0, #7 //search through 8 (7+1) bits. <-searches

FindLoop:
tst r1, #1 //ANDs input_word with 1, sets the Z flag accordingly.

beq NotFoundYet //didn't get a 0, jump forward
rsb r0, r0, #7 //searches=7-searches <- which bit is 0?
bx lr //Return found bit number

NotFoundYet:
lsr r1, r1, #1 //input_word=input_word>>1

sub r0, r0, #1 //Decrement searches
cmp r0, #0
bpl FindLoop //If searches>=0, do the loop again.
mov r0, #255 //We didn't find anything. Return 255 to signal that
bx lr

快速说明:我在这里使用 r1 作为变量,我听说你不应该这样做,因为编译器(我正在使用 gcc 将我的程序集“.S”文件链接到 C 文件)使用 r0-r3 来传递数据和接收数据功能。但是,正因为如此,它不会将这些寄存器用于重要的事情,所以我不必处理将内容插入堆栈的问题,从而节省了周期。

有什么问题?

当我尝试编译我的项目时,gcc 在 TST 行上给我一个汇编程序错误:

汇编器消息:错误:需要未移位的寄存器 -- `tst r1, #1’

这让我很困惑,因为我查看了 TST instruction 的 keil 站点和 LSR instruction我稍后会用它来将 r1 移动 1。但是他们都没有说不能一起工作。我在网上查找了有关此主题的其他讨论。我遇到了this discussion人们说告诉编译器在 ARM 模式下编译,但我的代码已经在 ARM 模式下运行,而不是 Thumb。我通过创建另一个 .global 子例程并尝试将一个大于 7 的立即数加到一个数字上来确认这一点,但确实它不起作用,就像 CPU 处于 ARM 模式时它不应该那样。

.global illegal_add
illegal_add:
add r0, r0, #20
bx lr

我知之甚少,也不知道如何尝试解决这个问题。如果有人对要尝试的事情有任何想法,请告诉我。感谢您的帮助。

最佳答案

我不是 100% 清楚问题出在哪里。您很可能忘记正确设置程序集。要解决此问题,请在文件开头发出这些指令:

.syntax unified
.cpu cortex-m4
.thumb

如果我把这些放在你的代码前面,它在我的机器上组装得很好。

一些一般提示:

  • 阅读哪些指令是 16 位可编码的,并尝试从中挑选指令。 16 位指令执行速度更快,消耗的内存更少。例如,您可以使用 lsrs r1, r1, #1 而不是 lsr r1, r1, #1 来获得 16 位指令。
  • 在旗帜操作方面更加聪明。许多指令已经为您设置了标志,如果您很聪明,您可能可以避免所有 tstcmp 指令。例如,如果您使用 subs r0, r0, #1 而不是 sub r0, r0, #1 您保存了一个字节(16 位指令)并且已经设置了 Z根据 r0 标记,为您节省后续的 cmp 指令。

关于c - 需要未移位的寄存器 - 汇编器在 TST 指令上抛出错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71881625/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com