如何在armv8汇编中创建数组?

发布于 2025-01-10 16:56:14 字数 219 浏览 0 评论 0原文

我觉得这是一个简单的问题,但到目前为止我无法在互联网上或我的任何教科书或课堂幻灯片中找到它。我有一个项目,如果不先创建一个数组就无法启动,所以我只是问如何将

int A[10];

(A[10] 当然是一个大小为 10 的数组)

转换为Armv8汇编代码

编辑:老实说,我不明白回答我的问题的问题,如果有帮助的话,它正在DS-5中编译

I feel like this is a simple question, but I am not able to find it anywhere on the internet or in any of my textbooks or powerpoints of my class so far. I have a project that I cannot start without first creating an array, so I am just asking how to translate

int A[10];

(A[10] of course being an array of size 10)

into Armv8 assembly code

edit: I honestly don't understand the questions in response to my question, it is being compiled in DS-5 if that helps

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

自由如风 2025-01-17 16:56:14

对于堆栈上的本地数组,它与其他架构几乎相同。只需减去堆栈指针并将您的值存储在那里即可。

对于 int a[10]sub sp, sp, #48 将在堆栈上分配数组。正如 Nate Eldredge 在评论中提到的,ARMv8 需要硬件进行 16 字节堆栈对齐,因此您不能编写 sub sp, sp, #40。您可以存储一些值,例如 *a = rstr r, [sp]str r, [sp, #4] a[1] = r,依此类推。

对于全局数组,只需在.bss中定义一个符号并为其分配足够的空间即可。

.bss
a:
    .zero 40

这会分配一个具有 10 个 32 位 int 的全局数组。

此类全局数组属于可执行文件中的某个部分。您可以使用自定义的读写可执行质量创建您喜欢的任何部分,但通常,非零初始化的可修改数据位于 .data 部分,而可修改的全零数据位于 < code>.bss 部分。有关基本详细信息,请参阅此处


您可以随时查看 Godbolt 来查看 C 中的每个语句如何转换为汇编语言。检查是否有优化,两者都会给你不同的有趣信息。

例如,以下是带有 -O3 的 Clang 如何在 C 语言中翻译这个简单的代码。

int a[10];

void f() {
    a[1] = 2;
}

void g() {
    volatile int b[10];
    b[3] = 4;
}

/*
  .text
f:
        adrp    x8, a+4
        mov     w9, #2
        str     w9, [x8, :lo12:a+4]
        ret
g:
        sub     sp, sp, #16
        mov     w8, #4
        str     w8, [sp, #12]
        add     sp, sp, #16
        ret

  .bss
a:
        .zero   40
*/

Godbolt 指令被过滤,因此部分切换可见。 (上面的块已过滤掉指令,但 .section 指令除外。)

了解本地数组和全局数组的分配和访问方式有何不同。我相信现在您有更具体的问题,以防您仍然遇到问题。

For local arrays on the stack, it's pretty much same as other architectures. Just subtract the stack pointer and store your values there.

For int a[10], sub sp, sp, #48 will allocate your array on the stack. As Nate Eldredge mentioned in a comment, ARMv8 requires 16-byte stack alignment from hardware, so you cannot write sub sp, sp, #40. You can store some value like str r, [sp] for *a = r, and str r, [sp, #4] for a[1] = r, and so on.

For global arrays, just define a symbol in .bss and allocate enough space for it.

.bss
a:
    .zero 40

This allocates a global array with 10 32-bit ints.

Such global arrays belong to a certain section in an executable file. You can make whatever section you like with custom read-write-executable qualities, but usually, non-zero-initialized modifiable data goes in the .data section, while modifiable all-zero data goes in the .bss section. See here for basic details.


You can always check Godbolt to see how each statement in C is translated to assembly. Check with and without optimizations, both will give you different interesting information.

For example, here's how Clang with -O3 translates this simple code in C.

int a[10];

void f() {
    a[1] = 2;
}

void g() {
    volatile int b[10];
    b[3] = 4;
}

/*
  .text
f:
        adrp    x8, a+4
        mov     w9, #2
        str     w9, [x8, :lo12:a+4]
        ret
g:
        sub     sp, sp, #16
        mov     w8, #4
        str     w8, [sp, #12]
        add     sp, sp, #16
        ret

  .bss
a:
        .zero   40
*/

Godbolt with directives not filtered so the section switching is visible. (The block above has directives filtered out, except for .section directives.)

See how a local array and a global array are allocated and accessed differently. I believe now you have more specific questions in case you still have a problem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文