【问题标题】:Initializing a bitarray object in assembly在程序集中初始化位数组对象
【发布时间】: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 位向量分配多少内存?谁在分配内存:通过构造函数的类还是消费类的客户端?

标签: assembly x86 bitarray


【解决方案1】:

你有一个初始化器,但没有一个构造器。

不同之处在于构造函数会分配内存,然后(可能是内联的)使用初始化器。

如果你使用构造函数,它会分配内存,但要分配多少?总是 64 位可以避免上面讨论的问题(写入你不一定拥有的内存)——但也需要 64 位来存储任何向量,即使只有 12 位。

此外,如果构造函数分配了 64 位,则无需 and 清除那些新分配的位,只需将(四字)零存储到其中。


可以使用各种更复杂的技术来创建消费客户端所需的足够大小的可变长度位向量,但这值得提出新的问题和答案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-09-01
    • 2018-06-22
    • 1970-01-01
    • 2017-02-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多