明确 TST 指令 - ARM 汇编
Clarity About TST Instruction - ARM Assembly
所以这里我有以下代码(ARMv6 程序集):
wait$:
ldr r2,[r0,#24] //read 32 bits from addr + 24 in r0 and store in r2
tst r2,#0x80000000 //????
bne wait$
我理解除 tst
指令之外的所有行。我在网上做了一些研究,我能找到的最佳定义是:
Test if a register is zero or minus. Perform a logical AND between a register and itself.
我在理解它的含义时遇到了一些困难,所以我试图使 C 等同于 tst
指令,这就是我得到的:
if(valRead & 0x80000000 != 0){}
上面的代码似乎不起作用。 tst
的更容易理解的定义是什么?它在 C 中的等价物是什么?
What is an easier to understand definition of tst
and what is the equivalent to it in C?
一些背景
C 中没有等效项,因为高级语言的工作方式不同于 CPU 具有“状态寄存器”(例如 ARM 或 x86)的语言:
在 C 或 C++ 等高级语言中,可以直接执行条件代码:
if(a < b) ...
在带有“状态寄存器”的 CPU 上,条件代码执行分两步完成:
- 第一步,您执行一些计算(例如
a-b
)。
在所谓的“状态寄存器”中,CPU 存储一些关于结果的“相关”信息(例如符号)。
- 在第二步中,实际的条件代码执行完成。
这只能根据“状态寄存器”中的信息来完成。
一个简化的例子:
操作 if(a < b) ...
可以通过以下方式在带有“状态寄存器”的 CPU 上执行:
/* Subtract b from a */
c = a - b;
/* (a < b) means that (a - b) is negative */
if(status.last_result_was_negative) ...
...但是,不需要操作的结果(示例中的c
)。
TST
和CMP
说明
要执行一个if(...)
操作,通常需要两个操作:
- 一个减法:
==
、<
、>
、<=
、>=
和 !=
. 需要它
- AND 运算:
需要检查值中的某些位是否已设置:
if(a & 0x8000) ...
...并且在这两种情况下,都不需要运算结果(差值或AND运算的结果)。
为此,有两条指令(CMP
和TST
)执行一个运算(CMP
执行减法,TST
执行与运算)但丢弃结果:
TST
运算执行与运算,根据结果设置“状态寄存器”中的信息,但丢弃实际结果。
这在像 if(a & 0xF000) ...
这样的行中是有意义的,您只对“状态寄存器”保存操作结果 a & 0xF000
是否为零感兴趣,但您是对 a & 0xF000
.
的实际结果不感兴趣
if(valRead & 0x80000000 != 0){}
你需要括号:
if((valRead & 0x80000000) != 0){}
否则编译器理解:
if(valRead & (0x80000000 != 0)){}
... 等同于:
if((valRead & 1) != 0){}
所以这里我有以下代码(ARMv6 程序集):
wait$:
ldr r2,[r0,#24] //read 32 bits from addr + 24 in r0 and store in r2
tst r2,#0x80000000 //????
bne wait$
我理解除 tst
指令之外的所有行。我在网上做了一些研究,我能找到的最佳定义是:
Test if a register is zero or minus. Perform a logical AND between a register and itself.
我在理解它的含义时遇到了一些困难,所以我试图使 C 等同于 tst
指令,这就是我得到的:
if(valRead & 0x80000000 != 0){}
上面的代码似乎不起作用。 tst
的更容易理解的定义是什么?它在 C 中的等价物是什么?
What is an easier to understand definition of
tst
and what is the equivalent to it in C?
一些背景
C 中没有等效项,因为高级语言的工作方式不同于 CPU 具有“状态寄存器”(例如 ARM 或 x86)的语言:
在 C 或 C++ 等高级语言中,可以直接执行条件代码:
if(a < b) ...
在带有“状态寄存器”的 CPU 上,条件代码执行分两步完成:
- 第一步,您执行一些计算(例如
a-b
)。
在所谓的“状态寄存器”中,CPU 存储一些关于结果的“相关”信息(例如符号)。 - 在第二步中,实际的条件代码执行完成。
这只能根据“状态寄存器”中的信息来完成。
一个简化的例子:
操作 if(a < b) ...
可以通过以下方式在带有“状态寄存器”的 CPU 上执行:
/* Subtract b from a */
c = a - b;
/* (a < b) means that (a - b) is negative */
if(status.last_result_was_negative) ...
...但是,不需要操作的结果(示例中的c
)。
TST
和CMP
说明
要执行一个if(...)
操作,通常需要两个操作:
- 一个减法:
==
、<
、>
、<=
、>=
和!=
. 需要它
- AND 运算:
需要检查值中的某些位是否已设置:
if(a & 0x8000) ...
...并且在这两种情况下,都不需要运算结果(差值或AND运算的结果)。
为此,有两条指令(CMP
和TST
)执行一个运算(CMP
执行减法,TST
执行与运算)但丢弃结果:
TST
运算执行与运算,根据结果设置“状态寄存器”中的信息,但丢弃实际结果。
这在像 if(a & 0xF000) ...
这样的行中是有意义的,您只对“状态寄存器”保存操作结果 a & 0xF000
是否为零感兴趣,但您是对 a & 0xF000
.
if(valRead & 0x80000000 != 0){}
你需要括号:
if((valRead & 0x80000000) != 0){}
否则编译器理解:
if(valRead & (0x80000000 != 0)){}
... 等同于:
if((valRead & 1) != 0){}