坚持使用 NASM 使用 MMX 指令对两个数组求和
Stuck at summing two arrays using MMX instructions using NASM
我被分配了以下任务:
Given two arrays with 16 elements: NIZA RESW 16 and NIZB RESW 16
store in the third array (NIZC RESW 16) the following values: NIZC[i]=NIZA[i]+NIZB[i] using MMX instructions and compiling it with NASM
这是我目前得到的:
%include "apicall.inc"
%include "print.inc"
segment .data
unos1 db "Array A: ", 0
unos2 db "Array B: ", 0
ispisC db "Array C : ", 0
segment .bss
NIZA RESW 16
NIZB RESW 16
NIZC RESW 16
segment .text
global start
start:
call init_console
mov esi,0
mov ecx, 16
mov eax, unos1
call print_string
call print_nl
unos_a:
call read_int
mov [NIZA+esi], eax
add esi, 2
loop unos_a
mov esi,0
mov ecx, 16
mov eax, unos2
call print_string
call print_nl
unos_b:
call read_int
mov [NIZB+esi], eax
add esi, 2
loop unos_b
movq mm0, qword [NIZA]
movq mm1, qword [NIZB]
paddq mm0, mm1
movq qword [NIZC], mm0
mov esi,NIZC
mov ecx,16
mov eax, ispisC
call print_string
call print_nl
ispis_c:
mov ax, [esi]
movsx eax, ax
call print_int
call print_nl
add esi, 2
loop ispis_c
APICALL ExitProcess, 0
编译给定的数组,并用下面两个数组测试后,第三个数组只存储了 16 个元素中的 4 个。(如下图所示)
有人知道为什么它只存储 16 个元素中的 4 个吗?感谢您的帮助。
如果您对函数有任何疑问 print_string
print_int
print_nl
是通过将其压入 EAX 寄存器来打印出字符串、新行和整数的函数,还要注意这是一个32 位程序。
Does anybody know why it only stores 4 elements out of 16?
因为你让你的 MMX 指令只对前 4 个数组元素进行操作。您需要一个循环来处理所有 16 个数组元素。
你的任务描述没有说明,但我看到你在打印前对 NIZC 的值进行了符号扩展,所以你似乎期待签名的结果。我还看到您使用 PADDQ
对 4 个字大小的输入进行操作。这将不会总是给出正确的结果!例如。如果 NIZA[0]=-1
和 NIZB[0]=5
,那么你会得到 NIZC[0]=4
但会发生从第一个单词到第二个单词的进位,从而使 NIZC[1]
错误。如果您使用正确版本的压缩加法,则不会发生这种情况:PADDW
.
你很幸运 mov [NIZA+esi], eax
和 mov [NIZB+esi], eax
上的大小错误。因为 NIZA 和 NIZB 在内存中按照您分配给它们的相同顺序彼此跟随,所以没有造成任何伤害。如果 NIZB 会被放在 NIZA 之前,那么分配 NIZB[15] 就会损坏 尼扎[0].
下面是我使用输入 subroutine in order to not have to repeat myself.
的部分重写
mov eax, unos1
mov ebx, NIZA
call MyInput
mov eax, unos2
mov ebx, NIZB
call MyInput
xor esi, esi
more:
movq mm0, qword [NIZA + esi]
paddw mm0, qword [NIZB + esi]
movq qword [NIZC + esi], mm0
add esi, 8
cmp esi, 32
jb more
emms ; (*)
...
MyInput:
call print_string
call print_nl
xor esi, esi
.more:
call read_int ; -> EAX
mov [ebx + esi], ax
add esi, 2
cmp esi, 32 ; Repeat 16 times
jb .more
ret
(*) 有关 emms
(空 MMX 状态)的信息,请参阅 https://www.felixcloutier.com/x86/emms
提示:您可以在一条指令中编写mov ax, [esi]
movsx eax, ax
:movsx eax, word [esi]
.
我被分配了以下任务:
Given two arrays with 16 elements: NIZA RESW 16 and NIZB RESW 16
store in the third array (NIZC RESW 16) the following values: NIZC[i]=NIZA[i]+NIZB[i] using MMX instructions and compiling it with NASM
这是我目前得到的:
%include "apicall.inc"
%include "print.inc"
segment .data
unos1 db "Array A: ", 0
unos2 db "Array B: ", 0
ispisC db "Array C : ", 0
segment .bss
NIZA RESW 16
NIZB RESW 16
NIZC RESW 16
segment .text
global start
start:
call init_console
mov esi,0
mov ecx, 16
mov eax, unos1
call print_string
call print_nl
unos_a:
call read_int
mov [NIZA+esi], eax
add esi, 2
loop unos_a
mov esi,0
mov ecx, 16
mov eax, unos2
call print_string
call print_nl
unos_b:
call read_int
mov [NIZB+esi], eax
add esi, 2
loop unos_b
movq mm0, qword [NIZA]
movq mm1, qword [NIZB]
paddq mm0, mm1
movq qword [NIZC], mm0
mov esi,NIZC
mov ecx,16
mov eax, ispisC
call print_string
call print_nl
ispis_c:
mov ax, [esi]
movsx eax, ax
call print_int
call print_nl
add esi, 2
loop ispis_c
APICALL ExitProcess, 0
编译给定的数组,并用下面两个数组测试后,第三个数组只存储了 16 个元素中的 4 个。(如下图所示)
有人知道为什么它只存储 16 个元素中的 4 个吗?感谢您的帮助。
如果您对函数有任何疑问 print_string
print_int
print_nl
是通过将其压入 EAX 寄存器来打印出字符串、新行和整数的函数,还要注意这是一个32 位程序。
Does anybody know why it only stores 4 elements out of 16?
因为你让你的 MMX 指令只对前 4 个数组元素进行操作。您需要一个循环来处理所有 16 个数组元素。
你的任务描述没有说明,但我看到你在打印前对 NIZC 的值进行了符号扩展,所以你似乎期待签名的结果。我还看到您使用 PADDQ
对 4 个字大小的输入进行操作。这将不会总是给出正确的结果!例如。如果 NIZA[0]=-1
和 NIZB[0]=5
,那么你会得到 NIZC[0]=4
但会发生从第一个单词到第二个单词的进位,从而使 NIZC[1]
错误。如果您使用正确版本的压缩加法,则不会发生这种情况:PADDW
.
你很幸运 mov [NIZA+esi], eax
和 mov [NIZB+esi], eax
上的大小错误。因为 NIZA 和 NIZB 在内存中按照您分配给它们的相同顺序彼此跟随,所以没有造成任何伤害。如果 NIZB 会被放在 NIZA 之前,那么分配 NIZB[15] 就会损坏 尼扎[0].
下面是我使用输入 subroutine in order to not have to repeat myself.
的部分重写 mov eax, unos1
mov ebx, NIZA
call MyInput
mov eax, unos2
mov ebx, NIZB
call MyInput
xor esi, esi
more:
movq mm0, qword [NIZA + esi]
paddw mm0, qword [NIZB + esi]
movq qword [NIZC + esi], mm0
add esi, 8
cmp esi, 32
jb more
emms ; (*)
...
MyInput:
call print_string
call print_nl
xor esi, esi
.more:
call read_int ; -> EAX
mov [ebx + esi], ax
add esi, 2
cmp esi, 32 ; Repeat 16 times
jb .more
ret
(*) 有关 emms
(空 MMX 状态)的信息,请参阅 https://www.felixcloutier.com/x86/emms
提示:您可以在一条指令中编写mov ax, [esi]
movsx eax, ax
:movsx eax, word [esi]
.