You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

通过汇编寻址逻辑反向推导C语言二维数组宏P、Q的取值

推导原理

C语言中int类型占4字节,二维数组按行优先存储,arr[M][N]的元素arr[x][y]的字节偏移计算公式为:
(x * N + y) * 4
其中N是二维数组的列数,也就是每行的元素个数。我们可以结合这个公式,对应汇编中的地址计算逻辑,反向推导出P和Q的取值。

变量对应关系

首先明确汇编寄存器和C变量的对应:

  • %edi/%rdi 对应函数入参 i
  • %esi/%rsi 对应函数入参 j

推导P的取值

mat2的定义为int mat2[Q][P],所以mat2[j][i]的字节偏移为 (j * P + i) * 4。
我们对应汇编中读取mat2的相关代码一步步计算:

leaq    (%rsi,%rsi,2), %rax    # rax = j + 2*j = 3j
leaq    (%rsi,%rax,4), %rdx    # rdx = j + 3j*4 = 13j
leaq    (%rdx,%rdx), %rax      # rax = 13j + 13j = 26j
addq    %rdi, %rax             # rax = 26j + i
movl    mat2(,%rax,4), %ecx    # 读取地址为 mat2 + rax*4 的值

可以看到汇编计算的mat2[j][i]偏移为(26j + i)*4,和C语言的偏移公式对比:
(j * P + i)*4 = (26j + i)*4
两边约去公共项后可得 P = 26。


推导Q的取值

mat1的定义为int mat1[P][Q],所以mat1[i][j]的字节偏移为 (i * Q + j) * 4。
我们对应汇编中写入mat1的相关代码一步步计算:

leaq    0(,%rdi,8), %rdx       # rdx = 8*i
subq    %rdi, %rdx             # rdx = 8i - i =7i
leaq    0(,%rdx,4), %rax       # rax = 7i *4 = 28i
addq    %rax, %rsi             # rsi = 28i + j
movl    %ecx, mat1(,%rsi,4)    # 写入地址为 mat1 + rsi*4 的值

可以看到汇编计算的mat1[i][j]偏移为(28i + j)*4,和C语言的偏移公式对比:
(i * Q + j)*4 = (28i + j)*4
两边约去公共项后可得 Q = 28。


最终结果

#define P 26
#define Q 28

注:你之前推导的表达式有误,错误原因是没有按汇编指令顺序分步计算寄存器值,按单条指令的运算逻辑逐行计算就能得到正确的偏移表达式。


内容的提问来源于stack exchange,提问作者Elie Meouchy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 00:57:01