【问题标题】:Assembly 8086 square root组装8086平方根
【发布时间】:2014-11-13 21:29:34
【问题描述】:

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

谢谢

【问题讨论】:

    标签: assembly input root masm x86-16


    【解决方案1】:

    给你:

    .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)
    

    在这里找到:Sqrt of 32bit number 您还可以在这里找到很多帮助:Calculate Sqrt in MASM

    【讨论】:

      【解决方案2】:

      我使用了“快速整数平方根”算法。我只是用了8086指令集。

      算法解释:

      汇编代码:

      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
      

      【讨论】:

        【解决方案3】:

        我的例程通过半节算法工作,并支持 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。 通过验证 if (M3 | M2)!=0 来测试 M 的平方是否长于 64 位;如果为真,则 square(M)>X,将上限 H 设置为 M。 如果不成立,则按如下方式处理 M 的低 32 位 (M1:M0) 的平方:

        (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)

        嗨!

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2023-03-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多