问题描述
我在我的 ASM 书中注意到作者使用 LENGTHOF str
来查找它正在搜索的字节大小。代码:
.data
alpha BYTE "ABCDEFGH",0
.code
mov edi,OFFSET alpha ; EDI points to the string
mov al,'F' ; search for the letter F
mov ecx,LENGTHOF alpha ; set the search count
cld ; direction = forward
repne scasb ; repeat while not equal
jnz quit ; quit if letter not found
dec edi ; found: back up EDI
有没有办法替换 LENGTHOF alpha
部分?我知道 len equ $-alpha
存在,但为了学习,我在幕后和“原始”实践中寻找更多。这样我才能更好地了解它的实际运作方式。
解决方法
你是对的,LENGTHOF alpha
可以替换为 len equ $-alpha
,声明在 alpha
定义的最后:
.data
alpha BYTE "ABCDEFGH",0
len equ $-alpha
.code
mov ecx,len
运算符 LENGTHOF
和 OFFSET
可以被视为返回字节数的函数名称,在您的示例中为 9
和 0
。它们是在汇编时间计算的,它们的名称取决于汇编器。在 MASM 中,它们被称为 operator LENGTHOF 和 operator OFFSET,在其他汇编器中,名称可能不同,例如参见 attributes in €ASM。
如果它不是汇编时常量字符串,那么您要么
-
已经知道它的长度(因为它是如何输入的)所以你仍然可以使用
rep scasb
作为慢速memchr
,将运行时变量长度作为 ECX。 -
或者如果它是一个“隐式长度”的 C 样式字符串并且您只有一个指针,您可以搜索终止
0
或'F'
(即实现strchr
) 使用一个循环检查这两件事。
或者更慢的方法是先搜索 0
以找到长度(即实现 strlen),然后将其用作 rep scasb
(memchr
) 的 ECX。
显然,所有这些搜索循环都可以通过手动循环中的简单指令完成,例如 mov
和 cmp
/jne
; rep scasb
不是魔术。
strchr
和 strlen
等是标准 C 函数的名称。我使用它们作为速记来描述您想要使用的搜索循环。