将C++代码转换为ARM汇编遇阻,求乘法相关代码实现指导
Hey there! Let's walk through how to translate that key sum calculation and array indexing logic into ARM assembly—this is a common pain point when moving from high-level C++ to bare-metal assembly, so let's break it down step by step.
First, let's recap the core line you're stuck on:
int sum = n1*n2 + result[i_n1 + i_n2] + carry;
We'll break this into discrete assembly operations, along with handling the i_n2++ and subsequent carry/result storage.
Key Assumptions (Adjust Based on Your Context)
Let's start with a typical register allocation for this logic (tweak based on your function's calling convention or existing code):
r0: Holdsn1(the current digit, 0-9)r1: Holdsn2(the current digit, 0-9)r2: Base address of theresultinteger arrayr3: Holdscarry(the carry value from the previous iteration)r4: Holdsi_n1(your loop index for the first number)r5: Holdsi_n2(your loop index for the second number)- We'll use temporary registers
r6-r9for intermediate calculations
Step 1: Calculate result[i_n1 + i_n2] Address & Load Value
ARM assembly uses byte-addressable memory, so since result is an array of int (4 bytes each), we need to scale our index by 4.
; Compute the index: i_n1 + i_n2 add r6, r4, r5 ; r6 = i_n1 + i_n2 lsl r6, r6, #2 ; r6 *= 4 (left shift 2 bits = multiply by 4 for int size) add r6, r6, r2 ; r6 = &result[i_n1 + i_n2] (base address + scaled index) ; Load the existing value from result into a register ldr r7, [r6] ; r7 = result[i_n1 + i_n2]
Step 2: Compute the sum Value
Now we'll build the sum step by step using ARM's arithmetic instructions:
; Multiply n1 * n2 mul r8, r0, r1 ; r8 = n1 * n2 ; Add the existing result value add r8, r8, r7 ; r8 += result[i_n1 + i_n2] ; Add the carry value add r8, r8, r3 ; r8 += carry → r8 now holds the full sum
Step 3: Update Carry & Store the Result
Next, we handle the carry calculation and save the remainder back to the result array:
; Compute new carry = sum / 10 (signed division for positive values) sdiv r3, r8, #10 ; r3 = sum / 10 → updates carry for next iteration ; Compute sum % 10 using a multiply-subtract instruction (more efficient than subtraction loops) mls r9, r3, #10, r8 ; r9 = sum - (carry * 10) → which is sum % 10 ; Store the remainder back to result[i_n1 + i_n2] str r9, [r6] ; result[i_n1 + i_n2] = sum % 10
Step 4: Increment i_n2
If i_n2 is stored in a register (like r5), increment it directly. If it's in memory, load it first, increment, then save back:
Register Version:
add r5, r5, #1 ; i_n2 += 1
Memory Version:
; Assume i_n2 is stored at memory address `i_n2_mem` ldr r5, [i_n2_mem] ; Load current i_n2 value into r5 add r5, r5, #1 ; Increment str r5, [i_n2_mem] ; Save updated value back to memory
Critical Notes for Your Implementation
- Register Preservation: If you're working within a function, remember that registers
r4-r11are "callee-saved" in most ARM calling conventions. Push them to the stack withpush {r4-r9}at the start of your function, and pop them back withpop {r4-r9}before returning. - Older ARM Versions: If you're targeting ARMv6 or earlier (no
SDIVinstruction), you'll need to implement division by 10 using repeated subtraction (since our values are small, this is feasible). - Byte Alignment: Always ensure your
resultarray is 4-byte aligned (standard forintarrays) to avoid alignment faults.
内容的提问来源于stack exchange,提问作者Shazee

