如何在汇编中找到负值的总和?
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?
我在 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?