如何用x86汇编计算2的幂次序列和?程序调试求助
Fixing Your x86 Assembly Program for Power Series Sum
Let's get your program working correctly. I've spotted a few critical issues in your code, and I'll break down the fixes plus share an optimized approach using a mathematical shortcut (since your base is fixed at 2).
Key Issues in Your Original Code
- Wrong string-to-integer conversion: You used
atod(for floating-point conversion) instead ofatoi(for integer conversion). This meant yourExponentvariable was getting garbage values instead of the input number. - Uninitialized register: Your
Functionstarted usingeaxwithout setting an initial value—mul ebxwas multiplying a random garbage value by 2, leading to invalid results. - Broken loop logic: The combination of
mul ebxandadd eax, ebxdidn't correctly accumulate the sum of each power of 2. You also weren't looping the correct number of times (you need N+1 iterations to cover 2^0 through 2^N). - Unsaved non-volatile registers: You modified
ebxin your function without saving/restoring it, which can break calling code (per x86 calling conventions, non-volatile registers likeebxmust be preserved).
Corrected Code (Optimized with Math Formula)
Since your sequence is a geometric series (2^N + 2^(N-1) + ... + 2^0), we can use the formula sum = 2^(N+1) - 1 to compute the result in constant time, no loops needed:
.586 .MODEL FLAT INCLUDE io.h .STACK 4096 .DATA Exponent DWORD ? Prompt BYTE "Enter an exponent", 0 string BYTE 40 DUP (?) resultLbl BYTE "The solution is", 0 Solution DWORD 20 DUP (?), 0 .CODE _MainProc PROC input Prompt, string, 40 ; Read input string atoi string ; Convert ASCII to integer (stores result in eax) mov Exponent, eax ; Save exponent to memory push Exponent ; Pass exponent as a parameter call calculate_sum ; Call our sum function add esp, 4 ; Clean up the stack dtoa Solution, eax ; Convert result to ASCII string output resultLbl, Solution ; Print the result mov eax, 0 ; Exit with return code 0 ret _MainProc ENDP ; Calculates 2^N + 2^(N-1) + ... + 2^0 using the formula 2^(N+1) - 1 ; Parameter: Exponent (N) pushed onto the stack ; Returns: Sum stored in eax calculate_sum PROC push ebp mov ebp, esp push ebx ; Save non-volatile register ebx mov ebx, [ebp+8] ; Get input exponent N mov eax, 1 ; Start with 2^0 shl eax, ebx ; Shift left N times: eax = 2^N shl eax, 1 ; Shift left once more: eax = 2^(N+1) sub eax, 1 ; Subtract 1 to get the sum pop ebx ; Restore ebx pop ebp ret calculate_sum ENDP END
If You Prefer a Loop-Based Implementation
If you want to stick with a loop to accumulate each term, here's the corrected calculate_sum function:
calculate_sum PROC push ebp mov ebp, esp push ebx push ecx push edx mov ebx, 2 ; Base value (2) mov ecx, [ebp+8] ; Get exponent N mov eax, 0 ; Initialize sum to 0 mov edx, 1 ; Start with the first term: 2^0 = 1 sum_loop: add eax, edx ; Add current term to the sum shl edx, 1 ; Compute next term: multiply by 2 (left shift) dec ecx ; Decrement counter jge sum_loop ; Loop until counter is negative (N+1 iterations) pop edx pop ecx pop ebx pop ebp ret calculate_sum ENDP
How the Loop Works
- We start with
edx = 1(2^0) and add it to the sum (eax). - Each iteration shifts
edxleft by 1 (equivalent to multiplying by 2) to get the next power of 2. - We loop N+1 times (from N down to 0) to include every term from 2^0 to 2^N.
内容的提问来源于stack exchange,提问作者IamSam Iam
相关产品推荐
相关产品推荐

