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

MASM64中vector6结构体元素相乘结果无法传递的问题求助

问题描述

需要将两个vector6结构体的对应元素相乘,并将结果写入另一个独立的vector6结构体。目前遇到的问题是:相乘后的结果无法正确传递——若传入已初始化的结构体,其值无变化;若传入未初始化的结构体,结果仅为0。

原代码

include /masm64/include64/masm64rt.inc

multiply_vectors proto p_base: qword, p_vector1: ptr vector6, p_vector2: ptr vector6, p_result: ptr vector6

MSGBOXPARAMS struct
    cbSize dword ?, ?
    hwndOwner qword ?
    hInstance qword ?
    lpszText qword ?
    lpszCaption qword ?
    dwStyle dword ?, ?
    lpszIcon qword ?
    dwContextHelpId qword ?
    lpfnMsgBoxCallback qword ?
    dwLanguageId dword ?, ?
MSGBOXPARAMS ends

vector6 struct
    x0 qword ?
    x1 qword ?
    x2 qword ?
    x3 qword ?
    x4 qword ?
    x5 qword ?
vector6 ends

IRS struct
    s_name dq ?
    s_profit dq ?
    s_tax dq ?
    s_count_fine dq ?
IRS ends

.const
    IDI_ICON equ 1001
    columns_count equ 6
    fmt0 db "New matrix:", 10,
            "|%3d, %3d, %3d, %3d, %3d, %3d|", 10,
            "|%3d, %3d, %3d, %3d, %3d, %3d|", 10,
            "Result 1: %d",10,
            "Result 2: %d",0
.data
    ; Matrix 6×6
    row0 vector6 <1,  4, 3,   9, 49, 48>
    row1 vector6 <1,  1, 3,  16,  7, 30>
    row2 vector6 <7, 51, 1, 333,  63, 8>
    row3 vector6 <1,  4, 3,   9, 49, 48>
    row4 vector6 <1,  1, 3,  16,  7, 30>
    row5 vector6 <7, 51, 1, 333,  63, 8>

    row2_0 vector6 <1,  4, 3,   9, 49, 48>
    row2_1 vector6 <1,  1, 3,  16,  7, 30>
    row2_2 vector6 <7, 51, 1, 333,  63, 8>
    row2_3 vector6 <1,  4, 3,   9, 49, 48>
    row2_4 vector6 <1,  1, 3,  16,  7, 30>
    row2_5 vector6 <7, 51, 1, 333,  63, 8>

    t_res qword ?

    row_res0 vector6 <?, ?, ?, ?, ?, ?>
    row_res1 vector6 <?, ?, ?, ?, ?, ?>
    row_res2 vector6 <?, ?, ?, ?, ?, ?>
    row_res3 vector6 <?, ?, ?, ?, ?, ?>
    row_res4 vector6 <?, ?, ?, ?, ?, ?>
    row_res5 vector6 <?, ?, ?, ?, ?, ?>

    res dq 0

    irsArray IRS <1000, 100, 3, 20>, <1001, 110, 4, 23> , <10002, 0, 2, 19> , <1003, 50, 5, 21>
    arrSize equ ($-irsArray) / type IRS
    average_profit dq 0
    res2 dq 0
    
    params0 MSGBOXPARAMS <>
    title0 db "MessageBox", 0
    text0 db 1024 dup(0)
.code
entry_point proc

    invoke multiply_vectors, 0, addr row2_0, addr row0, addr row_res0
    invoke multiply_vectors, 0, addr row2_1, addr row1, addr row_res1
    invoke multiply_vectors, 0, addr row2_2, addr row2, addr row_res2
    invoke multiply_vectors, 0, addr row2_3, addr row3, addr row_res3
    invoke multiply_vectors, 0, addr row2_4, addr row4, addr row_res4
    invoke multiply_vectors, 0, addr row2_5, addr row5, addr row_res5  

    invoke wsprintf, addr text0, addr fmt0, row_res0.x0, row_res0.x1, row_res0.x2, row_res0.x3, row_res0.x4, row_res0.x5, row_res1.x0, row_res1.x1, row_res1.x2, row_res1.x3, row_res1.x4, row_res1.x5, 0, res2
    mov params0.cbSize, sizeof MSGBOXPARAMS
    mov params0.hwndOwner, 0
    invoke GetModuleHandle, 0
    mov params0.hInstance, rax
    lea rax, text0
    mov params0.lpszText, rax
    lea rax, title0
    mov params0.lpszCaption, rax
    mov params0.dwStyle, MB_USERICON
    mov params0.lpszIcon, IDI_ICON
    mov params0.dwContextHelpId, 0
    mov params0.lpfnMsgBoxCallback, 0
    mov params0.dwLanguageId, LANG_NEUTRAL
    lea rcx, params0
    invoke MessageBoxIndirect
    invoke ExitProcess, 0
entry_point endp

multiply_vectors proc p_base: qword, p_vector1: ptr vector6, p_vector2: ptr vector6, p_result: ptr vector6

    lea rsi, p_vector1         
    lea rdi, p_vector2        
    lea rdx, p_result         
    mov rcx, columns_count    

    xor rax, rax               
loop_multiply:
    mov r8, qword ptr [rsi + (rax*8)]   
    mov r9, qword ptr [rdi + (rax*8)]       

    imul r8, r9                  
    mov qword ptr [rdx + rax*8], r8  

    inc rax                    
    cmp rax, rcx               
    jnl loop_multiply          

    ret
multiply_vectors endp
end

问题分析与修正

错误核心在于multiply_vectors过程中对指针参数的处理:

  • p_vector1、p_vector2、p_result本身已经是指向vector6结构体的指针(参数类型为ptr vector6),但代码中使用lea rsi, p_vector1是取参数变量在栈上的地址,而非参数指向的结构体地址,导致后续访问的是栈上的参数值本身,而非目标结构体的元素。

修正后的multiply_vectors过程:

multiply_vectors proc p_base: qword, p_vector1: ptr vector6, p_vector2: ptr vector6, p_result: ptr vector6

    mov rsi, p_vector1         ; 直接将指针加载到rsi,指向第一个vector6结构体
    mov rdi, p_vector2         ; 直接将指针加载到rdi,指向第二个vector6结构体
    mov rdx, p_result          ; 直接将指针加载到rdx,指向结果vector6结构体
    mov rcx, columns_count    

    xor rax, rax               
loop_multiply:
    mov r8, qword ptr [rsi + (rax*8)]   
    mov r9, qword ptr [rdi + (rax*8)]       

    imul r8, r9                  
    mov qword ptr [rdx + rax*8], r8  

    inc rax                    
    cmp rax, rcx               
    jl loop_multiply           ; 修正循环条件:jnl会提前退出,应该用jl继续循环直到rax等于rcx

    ret
multiply_vectors endp

额外修正点:

  • 循环退出条件jnl loop_multiply改为jl loop_multiply:原逻辑中当rax等于rcx(6)时,jnl会继续循环,导致越界访问;改为jl后,当rax从0到5时执行循环,共6次,刚好覆盖vector6的6个元素。

内容的提问来源于stack exchange,提问作者Влад

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 07:28:10