求助:x86汇编实现偶数索引(1、3、5…)求和代码异常排查
问题排查与修正:数组奇数索引元素求和(索引从0开始)
我在Godbolt C++编译器中运行两段测试数组时,一段结果正确,另一段错误。需要排查并修正代码,实现索引从0开始的奇数索引(即对应位置1、3、5…的元素)求和功能。
原代码
#ifdef __cplusplus #include <cstdio> #include <cassert> #else #include <stdio.h> #include <assert.h> #endif int solution_for_grade_6(int const * arr, unsigned int arr_size) { int result; __asm { mov ebx, 0; mov esi, [arr]; mov ecx, [arr_size]; jecxz emptyarr cycle: push ebx; mov eax, [ESI]; mov ebx, 2; cdq idiv ebx; cmp edx, 0; pop ebx; je next; add ebx, dword ptr[ESI]; next: add esi, 4; loop cycle; mov result, ebx; emptyarr: } return result; } int main() { int test_result; int test_arr1[] = { 0, 1000, 2250, -3000, 4444, 5678, 66543, 70, -80000, 900000 }; test_result = solution_for_grade_6(test_arr1, sizeof(test_arr1)/sizeof(test_arr1[0])); printf("Grade 6 result1 = %d\n", test_result); int test_arr2[] = { 0, -1, 2, -3, 4, -5, 6, -7, 8, -9}; test_result = solution_for_grade_6(test_arr2, sizeof(test_arr2)/sizeof(test_arr2[0])); printf("Grade 6 result2 = %d\n", test_result); return 0; }
问题分析
原汇编逻辑完全偏离需求:它是判断元素值是否为奇数(通过idiv 2检查余数是否非零),然后累加奇数元素。但需求是累加索引为奇数的元素(不管元素值奇偶),这就导致当测试数组的奇数索引元素刚好全是奇数时,结果巧合正确;一旦奇数索引出现偶数元素,结果就会错误。
修正后的代码
添加索引计数器,判断当前元素的索引是否为奇数,再决定是否累加:
#ifdef __cplusplus #include <cstdio> #include <cassert> #else #include <stdio.h> #include <assert.h> #endif int solution_for_grade_6(int const * arr, unsigned int arr_size) { int result; __asm { mov ebx, 0; // ebx存储求和结果,初始为0 mov esi, [arr]; // esi指向数组首元素 mov ecx, [arr_size]; // ecx存储循环次数 mov edi, 0; // edi存储当前元素索引,初始为0 jecxz emptyarr // 数组为空直接跳转到结束 cycle: // 判断当前索引是否为奇数:edi % 2 != 0 push ebx; mov eax, edi; mov ebx, 2; cdq idiv ebx; cmp edx, 0; pop ebx; je next; // 余数为0(索引偶数),跳过累加 // 索引为奇数,累加当前元素 add ebx, dword ptr[esi]; next: add esi, 4; // 移动到下一个int元素(4字节) inc edi; // 索引自增1 loop cycle; // ecx减1,不为0则继续循环 mov result, ebx; // 将结果存入result变量 emptyarr: } return result; } int main() { int test_result; int test_arr1[] = { 0, 1000, 2250, -3000, 4444, 5678, 66543, 70, -80000, 900000 }; test_result = solution_for_grade_6(test_arr1, sizeof(test_arr1)/sizeof(test_arr1[0])); // 预期结果:1000 + (-3000) + 5678 + 70 + 900000 = 903748 printf("Grade 6 result1 = %d\n", test_result); int test_arr2[] = { 0, -1, 2, -3, 4, -5, 6, -7, 8, -9}; test_result = solution_for_grade_6(test_arr2, sizeof(test_arr2)/sizeof(test_arr2[0])); // 预期结果:-1 + (-3) + (-5) + (-7) + (-9) = -25 printf("Grade 6 result2 = %d\n", test_result); return 0; }
内容的提问来源于stack exchange,提问作者harikishore V
相关产品推荐
相关产品推荐

