【问题标题】:x86-64 accessing element of arrayx86-64 访问数组的元素
【发布时间】:2020-10-19 21:41:05
【问题描述】:

您好,我是汇编语言初学者,movl (%rdi,%r12), %r10d movl (%rdi,%r12,4), %r10d 有区别吗?我尝试了它们,它们似乎都在做同样的工作——将 %r12 位置的 %rdi 元素保存到 %r10d。第二个例子中的 4 真的有必要吗?

【问题讨论】:

    标签: assembly x86-64 att addressing-mode


    【解决方案1】:

    是的,它们是不同的。

    假设例如%rdi = 0x12340000%r12 = 8。然后movl (%rdi,%r12), %r10d%r12 添加到%rdi 以形成有效地址,因此您从地址0x12340008 加载一个32 位dword。 4是SIB寻址方式的尺度参数;它会导致 %r12 在添加到 %rdi 之前乘以 4,因此使用 movl (%rdi,%r12,4), %r10d 您可以从地址 0x12340020 加载一个 32 位 dword。

    参见GNU as manual:“如果未指定scale,则scale 被视为1。”

    如果您尝试使用定义为的数组

    int32_t foo[] = {1,3,5,7,9,11,13,15,17,19,21,23,25};
    

    %rdi包含foo的地址,%r12 = 8同上,那么movl (%rdi,%r12), %r10d会加载%r10d的值5,但是movl (%rdi,%r12,4), %r10d会加载它的值@987654343 @。换句话说,问题在于您是将%rdi 视为字节计数还是32 位整数计数。

    如果它们在您的测试中似乎工作相同,那么您的测试有错误,或者两个不同的地址巧合包含相同的值,或者您的 %r12 为零,或者您的汇编程序损坏(不太可能)。

    【讨论】:

    • 谢谢!我发现了问题,我正在使用 movb 进行测试并认为 movl 的行为方式相同......
    • @M.Chen:他们还是和movb不一样。
    • 嗯 movb 不移动一个字节的数据?我想我会阅读手册并尝试理解说明,谢谢您的帮助!
    • @M.Chen:它确实移动了一个字节的数据。但是在上面的例子中,movb (%rdi, %r12), %r10b 会从地址0x12340008 移动字节,而movb (%rdi, %r12, 4), %r10b 会从地址0x12340020 移动字节。无论操作数大小如何,比例参数的作用都相同。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-19
    相关资源
    最近更新 更多