假设我有一个这样声明的缓冲区:
.section .bss
.lcomm buffer, 33
我将它推入堆栈,并将其作为参数传递给另一个需要 44 字节长度缓冲区的函数。
被调用函数有办法检查接收到的缓冲区长度是否为 44 字节吗?因为在缓冲区为空的情况下,您无法对其进行迭代并检查当前字节是否等于
$0
,因为这样它的所有字节都将等于 $0
。
更新:下面描述的所有缓冲区大小内容在与“常见”对象(
.lcomm
、.comm
中的.bss
)一起使用时都无法按描述工作。我会寻找一种处理常见对象的好方法。
您可以添加第三行来定义新符号
buffer_size
:
.section .bss
.lcomm buffer, 33
buffer_size = . - buffer
注意
.
是当前位置,即缓冲区之后,因此 . - buffer
是缓冲区开始 (buffer
) 和缓冲区之后 (.
) 之间的差值,即缓冲区的大小缓冲液。
您可以像任何其他符号一样以多种方式使用该
buffer_size
符号:
您可以在符号列表中看到它的值,例如与
nm
您可以通过向每个接受缓冲区指针参数的函数添加缓冲区大小参数,在 C 代码或汇编代码中使用此符号进行运行时检查。这就是你问题的直接答案。
您可以使用此符号通过链接器脚本进行链接时间检查,例如
-T check-buffer-size.x
或 -Wl,-T,check-buffer-size.x
:
/* check-buffer-size.x - link time check the buffer_size value */
SECTIONS {
}
INSERT AFTER .bss ;
ASSERT( (buffer_size == 44), "buffer_size is not the required 44" );
这给了你一个链接时断言,虽然经常有用,但似乎是一个不寻常的想法,以至于像C这样的编程语言只给你在编译时断言和运行时断言之间进行选择,但没有链接时间断言.
您可能还会遇到这样的情况:使用缓冲区末尾的符号比使用缓冲区大小更有用。在这种情况下,您可以为缓冲区的末尾定义一个符号
buffer_end
,例如
.section .bss
.lcomm buffer, 33
buffer_end = .
或
.section .bss
.lcomm buffer, 33
buffer_end:
然后将偏移量与
buffer_end
进行比较以了解循环结束条件等。