基于汇编与C代码框架推导二维数组参数M、N的取值
汇编代码注释与M、N推导过程
调用约定说明
该汇编遵循微软x64调用约定:函数第一个参数Array1存于%rcx,第二个参数Array2存于%rdx。
补全注释的汇编代码
arrayfunc: leaq 15992(%rdx),%rax # 计算Array2的总结束地址(最后一个元素的下一个8字节位置),作为倒序写入的起始基准 leaq -8(%rdx),%r10 # 存储Array2起始地址的前一个8字节位置,作为外层循环的终止边界 movq %rcx,%r9 # 保存Array1的基址到%r9,作为外层循环遍历Array1行的起始指针 .L2: # 对应C代码的外层i循环 leaq -400(%rdx), %r8 # 计算当前内层循环的终止边界:刚好是Array2当前行的起始地址减400字节(一行的大小) movq %r9,%rdx # 把Array1当前行的起始地址存到%rdx,供内层循环遍历行内元素 .L3: # 对应C代码的内层j循环 movslq (%rdx),%rcx # 读取Array1当前int类型元素,符号扩展为long类型存入%rcx subq $8,%rax # 倒序移动Array2的写入指针(每次减8,对应long类型的大小) addq $4,%rdx # 正序移动Array1的读取指针(每次加4,对应int类型的大小) movq %rcx,8(%rax) # 将读取到的Array1元素写入Array2的目标位置 cmpq %r8,%rax # 判断是否遍历完当前行所有元素,未完成则继续内层循环 jne .L3 addq $200,%r9 # 移动Array1的行指针到下一行(200是Array1一行的总字节数) cmpq %r10,%rax # 判断是否遍历完所有行,未完成则继续外层循环 jne .L2 ret
M、N推导步骤
推导N的值
Array1是int类型二维数组,每个元素占4字节,汇编中外层循环每次给Array1的行指针%r9加200字节,说明Array1每行的总大小为200字节。
因此每行的元素个数N = 200字节 / 4字节(单个int大小)= 50。
验证N的正确性
Array2是long类型二维数组,每个元素占8字节,若N=50,则Array2每行的大小为 50 * 8 = 400字节,和汇编中leaq -400(%rdx), %r8的400字节完全对应,验证N=50正确。
推导M的值
整个循环过程中,%rax从初始值Array2 + 15992降到终止值Array2 -8,总共减少了 15992 + 8 = 16000字节。每次内层循环%rax减8,对应处理一个元素,因此Array2的总元素个数为 16000 / 8 = 2000。
总元素个数 = M * N,已知N=50,因此M = 2000 / 50 = 40。
最终结果
M=40,N=50
内容的提问来源于stack exchange,提问作者Megan Darcy
相关产品推荐
相关产品推荐

