Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 迭代汇编中的数组以求解一般方程_Arrays_Assembly_X86 64_Nasm - Fatal编程技术网

Arrays 迭代汇编中的数组以求解一般方程

Arrays 迭代汇编中的数组以求解一般方程,arrays,assembly,x86-64,nasm,Arrays,Assembly,X86 64,Nasm,我正在使用NASM学习汇编语言,遇到了一个似乎无法解决的编程问题。该计划的目标是求解此方程: 对于那些看不到照片的人,方程式表示,对于长度为n的两个数组,数组a和数组b,找到:对于i=0到n-1,((ai+3)-(bi-4)) 我只需要使用三个通用寄存器,我已经找到了一个我认为可能有效的代码示例,但我在第16行和第19行中不断遇到逗号和操作数错误。我知道,为了遍历数组,需要将指针移动到每个索引,但由于两个数组的值不同(数组1是dw,数组2是db),我不确定如何解释这一点。我对汇编还是一个新手,任

我正在使用NASM学习汇编语言,遇到了一个似乎无法解决的编程问题。该计划的目标是求解此方程: 对于那些看不到照片的人,方程式表示,对于长度为n的两个数组,数组a和数组b,找到:对于i=0到n-1,((ai+3)-(bi-4))

我只需要使用三个通用寄存器,我已经找到了一个我认为可能有效的代码示例,但我在第16行和第19行中不断遇到逗号和操作数错误。我知道,为了遍历数组,需要将指针移动到每个索引,但由于两个数组的值不同(数组1是dw,数组2是db),我不确定如何解释这一点。我对汇编还是一个新手,任何帮助或指点都将不胜感激。 下面是我当前代码的图片:


您使用的是16位和8位数据,但使用的是64位寄存器。一般来说,处理器需要相同的数据大小,但不包括任何单个指令的操作数

cmp-rax,[n]
具有不同的数据大小,这是不允许的:
rax
是64位寄存器,
[n]
是16位数据项。因此,我们可以将其更改为
cmp-ax,[n]
,现在所有内容都是16位

add rbx,a[rax*4]
也混合了不同大小的操作数(不允许)。
rbx
是64位,
a[]
是16位。您可以将寄存器更改为
bx
,这是允许的。但我们也要注意,
*4
太多了,应该是
*2
,因为
dw
是16位数据(2字节),而不是32位(4字节)。由于您正在清除
rbx
,因此不需要
add
,只需
mov

添加rdx,字节b[rax]
也混合了不同的大小。
rax
是64位宽,而
b[]
的宽度为8位。请使用
dl
而不是
rdx
。没有什么可添加的,因此您应该使用
mov
而不是
add
。既然
dl
中有一个值,并且您以前清除了
rdx
,您可以切换到使用
dx
(从
dl
)这将具有16位的b[i]值

sub-rbx,[rdx]
有一个错误的尊重。这里您只想
sub-bx,dx


您没有使用标签
loop\u start
,因此没有循环。(在循环末尾添加一个向后分支。)

您使用的是16位和8位数据,而是64位寄存器。一般来说,处理器需要相同的数据大小,尽管任何一条指令的操作数不同

cmp-rax,[n]
具有不同的数据大小,这是不允许的:
rax
是64位寄存器,
[n]
是16位数据项。因此,我们可以将其更改为
cmp-ax,[n]
,现在所有内容都是16位

add rbx,a[rax*4]
也混合了不同大小的操作数(不允许)。
rbx
是64位,
a[]
是16位。您可以将寄存器更改为
bx
,这是允许的。但我们也要注意,
*4
太多了,应该是
*2
,因为
dw
是16位数据(2字节),而不是32位(4字节)。由于您正在清除
rbx
,因此不需要
add
,只需
mov

添加rdx,字节b[rax]
也混合了不同的大小。
rax
是64位宽,而
b[]
的宽度为8位。请使用
dl
而不是
rdx
。没有什么可添加的,因此您应该使用
mov
而不是
add
。既然
dl
中有一个值,并且您以前清除了
rdx
,您可以切换到使用
dx
(从
dl
)这将具有16位的b[i]值

sub-rbx,[rdx]
有一个错误的尊重。这里您只想
sub-bx,dx

您没有使用标签
loop\u start
,因此没有循环。(在循环末尾添加一个向后分支。)

…但由于两个数组的值不同(数组1是
dw
,数组2是
db
),我不确定如何解释这一点

解释了为什么“一直遇到逗号和操作数错误”。虽然可以恢复使用较小的寄存器(添加操作数大小前缀),但我的回答采用了不同的方法

指令集有
movzx
(零扩展移动)和
movsx
(符号扩展移动)指令来处理这些不同的大小。请参见下面的使用方法

我也应用了一些更改

  • 不要错过简化计算的机会:

    ((a[i]+3)-(b[i]-4))
    相当于
    (a[i]-b[i]+7)

  • 这些数组都不是空的,因此您可以将循环条件放在其主体下方

  • 如果方便的话,可以从末尾开始处理数组。求和操作不介意

请注意,存在额外的负偏移量
-2
-1
,以补偿循环控件在{2,1,0}时采用值{3,2,1}的事实这不会在指令中引入额外的位移分量,因为提到a和b数组实际上已经是位移了

虽然标记为x86-64,但您可以使用32位寄存器编写整个程序,而不需要REX前缀。结果相同

…但由于两个数组的值不同(数组1是
dw
,数组2是
db
),我不确定如何解释这一点

解释为什么您“不断遇到逗号和操作数错误”
       segment .data
  a         dw    12, 14, 16      ; array of three values        
  b         db    2, 4, 5         ; array of three values
  n         dw    3               ; length of both arrays
  result    dq    0               ; memory to result
      segment .text
      global main
  main:
      mov   rax, 0
      mov   rbx, 0
      mov   rdx, 0
  loop_start:
      cmp   rax, [n]
      jge   loop_end
      
      add   rbx, a[rax*4]   ; adding element of a at current index to rbx
      add   rbx, 3          ; adding 3 to current index value of array a in rbx
      
      add   rdx, BYTE b[rax]
      sub   rdx, 4

      sub   rbx, [rdx]
      add   [result], rbx
      
      xor   rbx, rbx
      xor   rdx, rdx
      add   rax, 1
  loop_end:
      ret 
     segment .data
a      dw    12, 14, 16      ; array of three values        
b      db    2, 4, 5         ; array of three values
n      dw    3               ; length of both arrays
result dq    0               ; memory to result
    segment .text
    global main
main:
       movzx rcx, word [n]
loop_start:
       movzx rax, word [a + rcx * 2 - 2]
       movzx rbx, byte [b + rcx - 1]
       lea   rax, [rax + rbx + 7]
       add   [result], rax
       dec   rcx
       jnz   loop_start
       ret
     segment .data
a      dw    12, 14, 16      ; array of three values        
b      db    2, 4, 5         ; array of three values
n      dw    3               ; length of both arrays
result dq    0               ; memory to result
    segment .text
    global main
main:
       movzx ecx, word [n]
loop_start:
       movzx eax, word [a + ecx * 2 - 2]
       movzx ebx, byte [b + ecx - 1]
       lea   eax, [eax + ebx + 7]
       add   [result], eax
       dec   ecx
       jnz   loop_start
       ret