x86-64汇编中如何交换二维数组的matrix[i][j]与matrix[j][i]值
x86-64 汇编实现方阵转置的交换逻辑修正方案
前置注意事项
RBX属于x86-64 System V调用约定中的被调用者保存寄存器,在函数中使用前必须压栈保存,返回前需要恢复,否则会触发调用方异常- 现有代码的内层j循环没有每次重置j计数器(
RBX)为0,第一次i循环跑完后j初始值错误,需要补充重置逻辑 - 你使用的是二级指针矩阵,寻址分两步:先取对应行的首指针,再根据列偏移取int元素,指针占8字节、int占4字节,偏移计算要对应类型长度
完整修正后的汇编代码
;extern void transpose_matrix_by_naive_in_asm(int **matrix, int matrixSize); ; RDI RSI section .text global transpose_matrix_by_naive_in_asm transpose_matrix_by_naive_in_asm: push rbx ; 保存被调用者寄存器RBX mov rax, 0 ; i = 0 loop_for_i: mov rbx, 0 ; 每次进入i循环重置j = 0 loop_for_j: cmp rax, rbx jl conditional_if ; 当i<j时执行交换 return_from_if: inc rbx cmp rbx, rsi jne loop_for_j inc rax cmp rax, rsi jne loop_for_i pop rbx ; 恢复RBX ret ; 函数返回 conditional_if: ; 1. 取第i行、第j行的首地址 mov rcx, [rdi + rax*8] ; rcx = matrix[i],指针占8字节,所以偏移是i*8 mov rdx, [rdi + rbx*8] ; rdx = matrix[j] ; 2. 读取两个元素的值 mov r8d, [rcx + rbx*4] ; r8d = matrix[i][j],int占4字节,列偏移是j*4 mov r9d, [rdx + rax*4] ; r9d = matrix[j][i] ; 3. 交换写回 mov [rcx + rbx*4], r9d ; matrix[i][j] = r9d mov [rdx + rax*4], r8d ; matrix[j][i] = r8d jmp return_from_if
交换逻辑说明
二级指针矩阵的元素寻址分为两步:
- 从一级指针数组
matrix中,按行号偏移取出对应行的首指针:行号为n时,偏移量为n*8(64位指针长度为8字节) - 从行指针指向的int数组中,按列号偏移取出元素:列号为m时,偏移量为
m*4(int长度为4字节)
交换时用两个32位通用寄存器暂存两个元素的值,再交叉写回对应地址即可完成交换。
内容的提问来源于stack exchange,提问作者Eduard
相关产品推荐
相关产品推荐

