어셈블리 언어에 익숙하지 않고 GCD를 계산하는 프로그램을 만들고 있지만 문제가 있습니다. 두 숫자를 입력 할 때 정답을 반환하지 않습니다. 어떤 제안? 나는 문제가 gcd 기능에 있다고 생각하지만 확실하지 않습니다.ARM 어셈블리에서의 GCD 함수가 제대로 작동하지 않음
.text
.global main
// Usage of the function: gcd(x,y), with the gcd returned in R0.
// Parameters: Register R0 must contain x, and register R1 must contain y.
gcd:
bal mod
cmp r0, #0
bne gcd
// end of gcd function
// Utility modulus function for you to use in your gcd function:
// Usage: mod(x,y), returns the modulus of x and y in register R0.
// Parameters: Register R0 must contain x, and register R1 must contain y.
mod: push {LR}
mov R3, R1
mov R1, #0
mov R2, #1
//Shift the denominator left until greater than numerator, then shift back
_shift_left:
//R3<<=1; //Denominator shift left
mov r3, r3, asl #1
//R2<<=1; //Division shift left
mov r2, r2, asl #1
//if(R0>R3)goto _shift_left;//Shift Left until Decrement/Division Greater than Numerator
cmp r0, r3 // compare r0 to r3
bgt _shift_left // branch if greater than to _shift_left label
//R3>>=1; //Shift Denominator right
mov r3, r3, asr #1
//R2>>=1; //Shift Division right
mov r2, r2, asr #1
//Loop and keep subtracting off the shifted Denominator
_subtract: //if(R0<R3)goto _done;
cmp r0, r3 // compare r0 to r3
blt _done // branch if less than to _done
//R1+=R2; //Increment division by the increment
adds r1, r2
//R0-=R3; //Subtract shifted Denominator with remainder of Numerator
subs r0, r3 //Shift right until denominator is less than numerator
_shift_right:
//if(R2==1) goto _subtract;
cmp r2, #1 // compare r2 to #1
beq _subtract // branch if equal to _subtract
//if(R3<=R0)goto _subtract;
cmp r3, r0 // compare r3 to r0
ble _subtract // branch if less than or equal to _subtract
//R2>>=1; //Shift Increment left
mov r2, r2, asr #1
//R3>>=1; //Shift Denominator left
mov r3, r3, asr #1
//goto _shift_right; //Shift Denominator until less than Numerator
bal _shift_right
//goto _subtract; //Keep Looping until the division is complete
bal _subtract
_done: pop {PC}
// end of mod function
main:
push {LR}
ldr R0, =welcome
bl printf
ldr R0, =prompt_a
bl printf
ldr R0, =scan_pat
ldr R1, =a
bl scanf
ldr r0, =prompt_b
bl printf
ldr r0, =scan_pat
ldr r1, =b
bl scanf
ldr r0, =a
ldr r0, [r0]
ldr r1, =b
ldr r1, [r1]
bl gcd
ldr r1, =gcd_result
str r0, [r1]
ldr r0, =gcd_msg
ldr r1, =a
ldr r1, [r1]
ldr r2, =b
ldr r2, [r2]
ldr r3, =gcd_result
ldr r3, [r3]
bl printf
mov r0, #0
pop {PC}
// end of main function
.data
welcome: .asciz "Welcome to the GCD Program!\n"
prompt_a: .asciz "Enter a value for A: "
prompt_b: .asciz "Enter a value for B: "
gcd_msg: .asciz "gcd(%d,%d) = %d\n"
scan_pat: .asciz "%d"
a: .word 0
b: .word 0
gcd_result: .word 0
이 기능을 상위 수준 언어로 작성하고 어셈블리로 변환하는 것이 좋습니다. C는 어셈블리를 수동으로 컴파일하기 쉬운 언어입니다. 또한 디버거를 사용하는 법을 배우십시오. 또한 플랫폼 호출 규칙에 대해 배우고 준수하는 것이 좋습니다. – EOF