【发布时间】:2021-01-19 05:01:55
【问题描述】:
作为(初学者)练习,我正在尝试在汇编中实现类似类的东西。为此,我想创建一个大小为 N 的 BitArray,并进行 init(size)、set(idx)、unset(idx)、get(idx) 和 print() 的操作。
我从init() 开始,这是我目前所拥有的:
bit_array_init:
# all this has to do is clear N bits (%rdi) starting at address (%rsi)
mov $-1, %rax # mask of all 1's
mov %dil, %cl
shl %cl, %rax # shift left by the number of bits, filling right-side with 0's
andq %rax, (%rsi) # because the mask is all 1's above the bit count, it doesn't matter
ret # if we 'extend too far' since &1 will have no affect
而且可以这样称呼:
movl $0b110110110110110110, -4(%rbp) # add bogus values to stack to confirm function's ok
# 1. Init the bitArray, b = BitArray(BIT_SIZE, address); allocated locally on the stack
mov $12, %edi # size of the bitarray
lea -4(%rbp), %rsi # where the bitarray starts at
call bit_array_init
它会故意只分配 12 位而不是“2 字节”之类的东西,而其他一切都保持原样(同样,它是用于练习/学习,而不是实际用于现实世界的东西)。
我对此有几个问题:
- 以上看起来像
init位数组的可接受方式吗?还是有更好的方法来做到这一点? - 我正在传递堆栈上某些东西的内存地址。这是大多数
init函数的工作方式吗?或者我应该传递(1)别的东西吗?或者 (2)init将传回它分配给的内存地址?
【问题讨论】:
-
如果有人想要 100 位怎么办?
-
@ErikEidt 它不起作用。我想为此它有 8 个字节的限制(在答案中可能会提到如何改进它以支持超过 8 个字节——我不知道该怎么做)。
-
好的,在这种情况下这通常会起作用,但它可能会执行 64 位的未对齐访问以初始化 12 位。此外,给定地址后 7 个字节的内存可能不存在,例如位于尚未分配给进程的另一个页面上。
-
如果它应该模仿一个类,那么调用者不应该知道内部结构或大小要求。如果您以某种方式对其进行优化,使其需要更多的存储空间而不仅仅是位呢?也许您扩展它以保持平价以快速返回。这些是您班级的内部私人成员。
init应该分配整个事情。此外,您仍然在指定大小之外书写,并且在不幸的情况下可能会崩溃(如果您越过页面边界进入无法访问的区域)。 -
@David542,是的。应该为 12 位向量分配多少内存?谁在分配内存:通过构造函数的类还是消费类的客户端?