如何在汇编中找到负值的总和?

How find sum of negative values in assembly?

我在 C++ 中使用内联汇编。但是,我的代码不能正常工作,它总是 returns 0。我想找到一些负值并显示。 你能帮帮我吗?

PS: 我用过debugging没找到问题


void func(const int* arr, size_t arr_rows, size_t arr_cols, int* result)
{
    int sum = 0;
    _asm
    {
        mov ebx, [arr] ///address
        mov edx, 0; //sum
        mov ecx, [arr_rows] // number of rows

        row_loop:
        push ecx // save number of rows
            xor esi, esi // reset column offset for the current row
            mov ecx, [arr_cols]  //  number of column
    col_loop :

            add ebx, esi;
            cmp ebx, 0
            jge bigger_case

            jl less_case
            jmp n_case

    less_case :
            add esi, 4
            add edx, dword ptr[ebx + esi];
            loop col_loop
            
    bigger_case:
            add esi, 4
            loop col_loop

      n_case: 
            add esi, 4
                add ebx, esi // move to the next row offset
                pop ecx // restore row loop counter
                loop row_loop;
            
    ending:
        mov sum, edx;
    }
    cout << sum<<" is answer"<<endl;
}


评论

  cmp ebx, 0

这会将地址与 0 进行比较。您需要比较数组中的值。

  add esi, 4
  add edx, dword ptr[ebx + esi];

这会将 下一个 元素添加到总和中。您需要 current 元素。

  loop col_loop
                <=== This is a 'fall through'
bigger_case:
  add esi, 4
  loop col_loop

如果该行的最后一个元素恰好是负数,那么代码中的这个失败将开始一个很长的循环!

  jge bigger_case
  jl less_case
  jmp n_case
less_case :

一旦你知道它既不大于也不等于,那么它就必须小于。在这里你确实可以在 less_case.

您无需使用额外的 ESI 偏移即可轻松寻址数组元素。总是 add ebx, 4,干净多了。

解决方案

您不需要使用嵌套循环来解决这个任务。只需计算元素总数并使用单个循环即可。

  xor  edx, edx
  mov  esi, [arr]
  mov  ecx, [arr_rows]
  imul ecx, [arr_cols]
more:
  mov  eax, [esi]
  test eax, eax         ; TEST is efficient to inspect the sign
  jns  skip
  add  edx, eax         ; Only adding negative values
skip:            
  add  esi, 4
  dec  ecx
  jnz  more

最好不要使用LOOP指令。参见 Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?