组件 8086 平方根



我正在尝试编写一个带有汇编的程序来提示用户输入,计算数字的平方根,然后输出数字的平方根。我真的不知道从哪里开始,所以任何指导将不胜感激。

谢谢

你来了:

.data?
int64 dq ?
squareRoot dd ?
.code
fild int64        ;load the integer to ST(0)
fsqrt             ;compute square root and store to ST(0)
fistp squareRoot  ;store the result in memory (as a 32-bit integer) and pop ST(0)

在这里找到: 32位数字的sqrt您还可以在此处找到很多帮助: 在 MASM 中计算 Sqrt

我使用了"快速整数平方根"算法。我刚刚使用了 8086 指令集。

算法说明:

  • http://en.wikipedia.org/wiki/Integer_square_root
  • http://ww1.microchip.com/downloads/en/AppNotes/91040a.pdf

汇编代码:

include 'emu8086.inc'
#make_COM#
org  100h   ; set location counter to 100h
mov [0710h],80h
mov [0720h],100h
mov si,0
mainloop:
inc si
mov ax,[0710h]
mov bx,[0720h]
mul ax
cmp ax,bx
je exit
jna lessthan
ja greaterthan
exit:
mov ax,[0710h]
ret
lessthan:
mov [0740h],1
mov di,si 
call createnumber
mov bx,[0710h]
or ax,bx
mov [0710h],ax
jmp mainloop
greaterthan:
mov dx,[0740h]
cmp dx,1
je isenteredbefore
mov ax,[0710h]
shr ax,1
mov [0710h],ax
jmp mainloop 
isenteredbefore:
mov di,si
dec di
dec di
call rorwithone
mov bx,[0710h]
and ax,bx
mov bx,ax
mov di,si
call createnumber
or ax,bx
mov [0710h],ax
jmp mainloop  
createnumber PROC
mov ax,80h
mov cx,di
createnumberloop:
shr ax,1
dec cx
cmp cx,0
jne createnumberloop
ret              
createnumber ENDP                  
rorwithone PROC
mov [0730h],80h
mov cx,di
rorwithoneloop:
mov ax,[0730h]
sar ax,1
mov bx,[0730h]
or ax,bx
mov [0730h],ax 
dec cx
cmp cx,0
jne rorwithoneloop
ret              
rorwithone ENDP     
end

这是我的例程通过半节算法工作,并支持 64 位无符号整数的平方根。遵循 8086+ CPU 新的实模式代码:

Function NewSqrt16(XLow,XHigh:LongInt):LongInt; Assembler;
Var X0,X1,X2,X3,
    H0,H1,H2,H3,
    L0,L1,L2,L3,
    M0,M1,M2,M3:Word;
Asm
     LEA   SI,XLow
     Mov   AX,[SS:SI]
     Mov   BX,[SS:SI+2]
     LEA   SI,XHigh
     Mov   CX,[SS:SI]
     Mov   DX,[SS:SI+2]
{==============================================================================}
    {INPUT: DX:CX:BX:AX = X
     OUPUT: DX:AX= Sqrt(X).
     ------------------------
         X0    :    X1    :    X2    :    X3    -> X
         H0    :    H1    :    H2    :    H3    -> H
         L0    :    L1    :    L2    :    L3    -> L
         M0    :    M1    :    M2    :    M3    -> M
         AX    ,    BX    ,    CX    ,    DX    ,
         ES    ,    DI    ,    SI               -> Temp. reg.
     ------------------------}
     Mov   [X0],AX           {  ...}
     Mov   [X1],BX           {  ...}
     Mov   [X2],CX           {  ...}
     Mov   [X3],DX           {  Stack <- X}
     Mov   [H0],AX           {  ...}
     Mov   [H1],BX           {  ...}
     Mov   [H2],CX           {  ...}
     Mov   [H3],DX           {  Stack <- H= X}
     Mov   [L0],Word(1)      {  ...}
     Mov   [L1],Word(0)      {  ...}
     Mov   [L2],Word(0)      {  ...}
     Mov   [L3],Word(0)      {  Stack <- L= 1}
     Add   AX,1              {  ...}
     AdC   Bx,0              {  ...}
     AdC   Cx,0              {  ...}
     AdC   Dx,0              {  X= X+1}
     RCR   Dx,1              {  ...}
     RCR   Cx,1              {  ...}
     RCR   Bx,1              {  ...}
     RCR   Ax,1              {  X= (X+1)/2}
     Mov   [M0],AX           {  ...}
     Mov   [M1],BX           {  ...}
     Mov   [M2],CX           {  ...}
     Mov   [M3],DX           {  Stack <- M= (X+1)/2}
{==============================================================================}
@@LoopBegin:                 {Loop restart label}
     Mov   AX,[M3]           {If M is more ...}
     Or    AX,[M2]           {... then 32 bit ...}
     JNE   @@LoadMid         {... then Square(M)>X, jump}
    {DX:AX:CX:SI= 64 Bit square(Low(M))}
     Mov   AX,[M0]           {AX <- A=Low(M)}
     Mov   CX,AX             {CX <- A=Low(M)}
     Mul   AX                {DX:AX <- A*A}
     Mov   SI,AX             {SI <- Low 16 bit of last mul.}
     Mov   BX,DX             {BX:SI <- A*A}
     Mov   AX,[M1]           {AX <- D=High(M)}
     XChg  CX,AX             {AX <- A=Low(M); CX <- D=High(M)}
     Mul   CX                {DX:AX <- A*D=Low(M)*High(M)}
     XOr   DI,DI             {...}
     ShL   AX,1              {...}
     RCL   DX,1              {...}
     RCL   DI,1              {DI:DX:AX <- A*D+D*A= 2*A*D (33 Bit}
     Add   AX,BX             {...}
     AdC   DX,0              {...}
     AdC   DI,0              {DI:DX:AX:SI <- A*(D:A)+(D*A) ShL 16 (49 Bit)}
     XChg  CX,AX             {AX <- D=High(M); CX <- Low 16 bit of last mul.}
     Mov   BX,DX             {DI:BX:CX:SI <- A*(D:A)+(D*A) ShL 16 (49 Bit)}
     Mul   AX                {DX:AX <- D*D}
     Add   AX,BX             {...}
     AdC   DX,DI             {DX:AX:CX:SI <- (D:A)*(D:A)}
    {------------------------}
     Cmp   DX,[X3]           {Compare High(Square(M)):High(X)}
@@LoadMid:                   {Load M in DX:BP:BX:DI}
     Mov   DI,[M0]           {...}
     Mov   BX,[M1]           {...}
     Mov   ES,[M2]           {...}
     Mov   DX,[M3]           {DX:ES:BX:DI <- M}
     JA    @@SqrMIsMoreThenX {If High(Square(M))>High(X) then Square(M)>X, jump}
     JB    @@SqrMIsLessThenX {If High(Square(M))<High(X) then Square(M)<X, jump}
     Cmp   AX,[X2]           {Compare High(Square(M)):High(X)}
     JA    @@SqrMIsMoreThenX {If High(Square(M))>High(X) then Square(M)>X, jump}
     JB    @@SqrMIsLessThenX {If High(Square(M))<High(X) then Square(M)<X, jump}
     Cmp   CX,[X1]           {Compare High(Square(M)):High(X)}
     JA    @@SqrMIsMoreThenX {If High(Square(M))>High(X) then Square(M)>X, jump}
     JB    @@SqrMIsLessThenX {If High(Square(M))<High(X) then Square(M)<X, jump}
     Cmp   SI,[X0]           {Compare Low(Square(M)):Low(X)}
     JA    @@SqrMIsMoreThenX {If Low(Square(M))>Low(X) then Square(M)>X, jump}
    {------------------------}
@@SqrMIsLessThenX:           {Square(M)<=X}
     Mov   [L0],DI           {...}
     Mov   [L1],BX           {...}
     Mov   [L2],ES           {...}
     Mov   [L3],DX           {L= M}
     Jmp   @@ProcessMid      {Go to process the mid value}
    {------------------------}
@@SqrMIsMoreThenX:           {Square(M)>X}
     Mov   [H0],DI           {...}
     Mov   [H1],BX           {...}
     Mov   [H2],ES           {...}
     Mov   [H3],DX           {H= M}
    {------------------------}
@@ProcessMid:                {Process the mid value}
     Mov   SI,[H0]           {...}
     Mov   CX,[H1]           {...}
     Mov   AX,[H2]           {...}
     Mov   DX,[H3]           {DX:AX:CX:SI <- H}
     Mov   DI,SI             {DI <- H0}
     Mov   BX,CX             {BX <- H1}
     Add   SI,[L0]           {...}
     AdC   CX,[L1]           {...}
     AdC   AX,[L2]           {...}
     AdC   DX,[L3]           {DX:AX:CX:SI <- H+L}
     RCR   DX,1              {...}
     RCR   AX,1              {...}
     RCR   CX,1              {...}
     RCR   SI,1              {DX:AX:CX:SI <- (H+L)/2}
     Mov   [M0],SI           {...}
     Mov   [M1],CX           {...}
     Mov   [M2],AX           {...}
     Mov   [M3],DX           {M <- DX:AX:CX:SI}
    {------------------------}
     Mov   AX,[H2]           {...}
     Mov   DX,[H3]           {DX:AX:BX:DI <- H}
     Sub   DI,[L0]           {...}
     SbB   BX,[L1]           {...}
     SbB   AX,[L2]           {...}
     SbB   DX,[L3]           {DX:AX:BX:DI <- H-L}
     Or    BX,AX             {If (H-L) >= 65536 ...}
     Or    BX,DX             {...}
     JNE   @@LoopBegin       {... Repeat @LoopBegin else goes forward}
     Cmp   DI,2              {If (H-L) >= 2 ...}
     JAE   @@LoopBegin       {... Repeat @LoopBegin else goes forward}
{==============================================================================}
     Mov   AX,[M0]           {...}
     Mov   DX,[M1]           {@Result <- Sqrt}
End;

输入中的此函数接收一个 64 位数字 (XHigh:XLow) 并返回它的 32 位平方根。使用四个局部变量:

X, the copy of input number, subdivided in four 16 Bit packages (X3:X2:X1:X0).
H, upper limit, subdivided in four 16 Bit packages (H3:H2:H1:H0).
L, lower limit, subdivided in four 16 Bit packages (L3:L2:L1:L0).
M, mid value, subdivided in four 16 Bit packages (M3:M2:M1:M0).

将下限 L 初始化为 1;将上限 H 初始化为输入数字 X;将中间值 M 初始化为 (H+1)>>1。通过验证 M 的平方是否大于 64 位来测试是否长于 64 位 (M3 |M2)!=0;如果为真,则 square(M)>X 将上限 H 设置为 M。如果不是真,则按如下方式处理 M (M1:M0) 的下 32 位的平方:

(M1:M0)*(M1:M0)=
M0*M0+((M0*M1)<<16)+((M1*M0)<<16)+((M1*M1)<<32)=
M0*M0+((M0*M1)<<17)+((M1*M1)<<32)
如果 M 的下限 32 位的平方大于 X,

则将上限 H 设置为 M;如果 M 的下 32 位的平方小于或等于 X 值,则将下限 L 设置为 M。处理中间值 M,将其设置为 (L+H)>>1。如果 (H-L)<2 那么 M 是 X 的平方根,否则去测试 M 的平方是否长于 64 位并运行以下指令。

你好!

最新更新