我想写一个程序,你输入两个数字并得到最大的公约数 使用以下伪代码:
Euclid(a, b)
while (b != 0)
{
r = a mod b
a = b
b = r
}
return a
这是我当前的版本,它给出了一个错误:52:操作码和操作数的无效组合。
%include "asm_io.inc"
segment .data
prompt1 db "Enter a number: ", 0
prompt2 db "Enter another number: ", 0
segment .bss
input1 resd 1
input2 resd 1
segment .text
global asm_main
asm_main:
enter 0,0 ; setup routine
pusha
mov eax, prompt1
call print_string
call read_int
push eax
mov eax, prompt2
call print_string
call read_int
push eax
call euclid
call print_int
popa
mov eax, 0 ; return back to C
leave
ret
; Function euclid
euclid:
push ebp
mov ebp, esp
mov ebx, [ebp+8]
mov ecx, [ebp+12]
_while:
div ecx,ebx
mov ebx,ecx
mov ecx,edx
cmp ecx,0
jz _end
jmp _while
_end:
mov eax,ebx
pop ebp
ret
我对assembly和nasm完全不熟悉,我希望你能帮助我找到错误或错误的语法。
答案 0 :(得分:1)
没有div ecx,ebx
指令。如果您要执行ecx
/ ebx
,那么您必须使用div r/m32
形式,将edx
和eax
形成的64位数量除以给定的操作数。因此,您必须注意将edx
清零以获得32位红利(或使用符号扩展cdq
指令进行签名操作)。
代码可能如下所示:
xor edx, edx
mov eax, ecx
div ebx ; eax = ecx / ebx, remainder in edx
如有疑问,请使用instruction set reference。
您的代码中可能存在逻辑错误,我只回答了您提出的问题。
答案 1 :(得分:0)
代码中的错误是您的逻辑。你应该返回'r'而不是'a',并且在'while loop'中你应该将'a mod b'的值与零而不是'b'的值进行比较。还有更多的情况是由于两个整数的比较而发生的,例如,第一个整数可以小于或大于第二个整数。在算法中也应该考虑那些比较。我根本不知道nasm或汇编,但你应该尝试下面的psudo代码。 'min(a,b)'是一个你应该编写的函数,它返回'a'和'b'的最小值。我不知道nasm或汇编的语法,但逻辑应该运行良好。一切顺利!< / p>
Euclid(a,b)
if(min(a,b)==a){
while (b mod a != 0) {
r = b mod a
b = a
a = r
}
return r
}
else{
while(a mod b!=0){
r = a mod b
a = b
b = r
}
return r
}
答案 2 :(得分:0)
这是一个使用内联汇编计算最大公约数的程序。
#include <stdio.h>
int gcd( int a, int b ) {
int result ;
/* Compute Greatest Common Divisor using Euclid's Algorithm */
__asm__ __volatile__ ( "movl %1, %%eax;"
"movl %2, %%ebx;"
"CONTD: cmpl $0, %%ebx;"
"je DONE;"
"xorl %%edx, %%edx;"
"idivl %%ebx;"
"movl %%ebx, %%eax;"
"movl %%edx, %%ebx;"
"jmp CONTD;"
"DONE: movl %%eax, %0;" : "=g" (result) : "g" (a), "g" (b)
);
return result ;
}
int main(int argc, const char * argv[])
{
printf("%d \n", gcd(30, 50));
return 0;
}
我在这里找到了它,http://www.codeproject.com/Articles/15971/Using-Inline-Assembly-in-C-C