Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 用edi代替eax求最大公约数_Assembly_X86_Masm_Greatest Common Divisor - Fatal编程技术网

Assembly 用edi代替eax求最大公约数

Assembly 用edi代替eax求最大公约数,assembly,x86,masm,greatest-common-divisor,Assembly,X86,Masm,Greatest Common Divisor,我试图写一个代码来找到最大公约数(GCD)。我编写的代码工作得非常好,但是我需要使用EDI寄存器而不是EAX寄存器来编写相同的代码。但当我在代码中将“EAX”替换为“EDI”时,它并没有按预期工作。我相信问题出在DIV身上(尽管不确定) div指令(以及idiv指令)使用隐含的(“硬连线”)寄存器来分配红利、商和余数;只有除数是显式的(由程序员决定) 更具体地说,股息必须在(e/r)dx:(e/r)ax中,商将放在(e/r)ax中,剩余部分将放在(e/r)dx中。在您的情况下(32位,以esi作

我试图写一个代码来找到最大公约数(GCD)。我编写的代码工作得非常好,但是我需要使用EDI寄存器而不是EAX寄存器来编写相同的代码。但当我在代码中将“EAX”替换为“EDI”时,它并没有按预期工作。我相信问题出在DIV身上(尽管不确定)


div
指令(以及
idiv
指令)使用隐含的(“硬连线”)寄存器来分配红利、商和余数;只有除数是显式的(由程序员决定)

更具体地说,股息必须在
(e/r)dx:(e/r)ax
中,商将放在
(e/r)ax
中,剩余部分将放在
(e/r)dx
中。在您的情况下(32位,以
esi
作为除数),64位被除数必须在
edx:eaz
中(或者,用
edx
中的最高32位和
eax
中的最低32位分成两半)

除了
div
idiv
指令之外,没有其他选择(除了它们本身-即,您可以使用
idiv
而不是
div
,但它不会有帮助),因为没有其他选择,您需要将值从
edi
移动/复制到
eax
(并将结果从
eax
移动/复制回
edi
);如果这样移动/复制值,最好在循环外部(而不是在循环内部)进行

换句话说,您希望您已经拥有的几乎所有代码(使用
eax
)保持不变,并且只希望在开始时使用
mov-eax,edi
,在结束时使用
mov-edi,eax
(如果
eax
,则可能使用
push-eax
pop-eax


另一个选项是期望调用者将值放入
eax
本身,这可能更有效(因为调用者可能对它用于什么的寄存器没有太多限制);但这可以转化为“停止想做你想做的事情”。

指令(和
idiv
指令)使用隐含(“硬连线”)寄存器进行除数、商和余数;只有除数是显式的(由程序员确定)

更具体地说,被除数必须是
(e/r)dx:(e/r)ax
,商将被放入
(e/r)ax
,其余部分将被放入
(e/r)dx
。在您的情况下(32位,以
esi
作为除数),64位被除数必须是
edx:eaz
(或者,将edx中的最高32位和eax中的最低32位一分为二)

除了
div
idiv
指令之外,没有其他选择(除了它们本身-即,您可以使用
idiv
而不是
div
,但它不会有帮助),因为没有其他选择,您需要将值从
edi
移动/复制到
eax
(并将结果从
eax
移动/复制回
edi
);如果这样移动/复制值,最好在循环外部(而不是在循环内部)进行

换句话说,您希望您已经拥有的几乎所有代码(使用
eax
)保持不变,并且只希望在开始时使用
mov-eax,edi
,在结束时使用
mov-edi,eax
(如果
eax
,则可能使用
push-eax
pop-eax


另一个选项是期望调用者将值放入
eax
本身,这可能会更有效(因为调用者可能对它用于什么的寄存器限制更少);但这可以转化为“停止想做你想做的事情”.

DIV
使用
(e/r)ax
(e/r)dx
的组合作为红利。请参阅英特尔手册。
DIV
使用
(e/r)ax
(e/r)dx
的组合作为红利。请参阅英特尔手册。
.386
.model flat, Stdcall
.stack 4096
ExitProcess PROTO, dwExitCode:DWORD

.data
    x sword 33
    y sword 242


.code
main proc
    mov eax, 0
    mov esi, 0
    mov ax, x
    mov si, y

    
main endp
;----------
CalcGCD Proc    ;calculate greatest common divisor
;receive x in eax(int 1) and y in esi(int 2)
;returns x in eax = gcd
;----------
    push esi
    push edx
    cmp eax,0 ;if x >=0 
    jge LX
    neg eax   ; x was negative, so make negative
LX:
    cmp esi,0 ;if y >=0 
    jge LY
    neg esi   ; y was negative, so make negative
LY:
DO: mov edx,0
    DIV esi  ; edx= eax%esi
    mov eax, esi ;eax =esi
    mov esi,edx  ;esi=edx
    cmp esi, 0  ;while esi>0
    jg do ;jump back to DO

    pop edx
    pop esi
    ret
CalcGCD ENDP


end main