Roberto Meneses
Roberto Meneses

Reputation: 45

ASM 8086 division without div

I need to write in asm 8086 a program like b=a/6 but without the DIV instruction. I know how to do it with SAR but only 2,4,8,16...

mov ax,a
sar ax,1 ;//div a by 2
mov b,ax

my question is how can I do it to div by 6?

Upvotes: 3

Views: 5452

Answers (4)

Řrřola
Řrřola

Reputation: 6297

Since you've used the sar instruction in your example, I assume you need signed division by 6.

The following code uses multiplication by the reciprocal constant. It rounds the result down to −∞:

mov ax,0x2AAB   ; round(0x10000/6)
imul A          ; DX:AX contains the signed 32-bit result of the multiplication
mov B,dx        ; take only the upper 16 bits

If you need the result rounded towards 0, increase negative results by one:

      mov  ax,0x2AAB
      imul A
      test dx,dx  ; set FLAGS according to DX
      jns  skip
      inc  dx      ; increase DX if it was negative
skip: mov  B,dx

Finally, if you need unsigned division by 6, you need a more precise constant and a shift:

mov ax,0xAAAB  ; round(0x40000/6)
mul A          ; DX:AX contains the unsigned 32-bit result of the multiplication
shr dx,1
shr dx,1       ; shift DX right by 2 (8086 can't do "shr dx,2")
mov B,dx

Upvotes: 1

old_timer
old_timer

Reputation: 71506

From grade school

x/6 = x * 1/6;

Look at what happens when you let the C compiler do it

unsigned short fun ( unsigned short x )
{
    return(x/6);
}

32 bit x86

0000000000000000 <fun>:
   0:   0f b7 c7                movzwl %di,%eax
   3:   69 c0 ab aa 00 00       imul   $0xaaab,%eax,%eax
   9:   c1 e8 12                shr    $0x12,%eax
   c:   c3                      retq 

32 bit arm

00000000 <fun>:
   0:   e59f3008    ldr r3, [pc, #8]    ; 10 <fun+0x10>
   4:   e0802093    umull   r2, r0, r3, r0
   8:   e1a00120    lsr r0, r0, #2
   c:   e12fff1e    bx  lr
  10:   aaaaaaab

same story. Translate that to 8086.

so 6 = 3 * 2, so we really need to divide by 3. then adjust

unsigned short fun ( unsigned short x )
{
    return(x/3);
}

00000000 <fun>:
   0:   e59f3008    ldr r3, [pc, #8]    ; 10 <fun+0x10>
   4:   e0802093    umull   r2, r0, r3, r0
   8:   e1a000a0    lsr r0, r0, #1
   c:   e12fff1e    bx  lr
  10:   aaaaaaab

one less bit of shift. One of the shifts is to increase precision the other is because there is a divide by 2 in there.

You can do the subtraction loop of course. Otherwise it is long division which is actually pretty easy to code.

Upvotes: 0

1201ProgramAlarm
1201ProgramAlarm

Reputation: 32732

The approach given an another answer is simple brute force loop, and can take a while for large values of a. This is a version that uses larger chunks (working it like a long division problem) specifically coded to divide a signed number by 6:

; signed divide by 6
    mov ax,a
    mov cx,1000h  ; initial count of how many divisors into ax to check for
    mov bx,6000h  ; value of "divisor * cx"
    xor dx,dx     ; result
top:
    cmp ax,bx
    jl skip
    ; we can fit "cx" copies of the divisor into ax, so tally them
    add dx,cx
    sub ax,bx
    ; optionally can have a "jz done" here to break out of the loop
skip:
    shr bx,1
    shr cx,1
    jnz top

    ; copy result into ax
    mov ax,dx

If you need to divide something other than 6, the initial cx and bx values need to be adjusted. cx is the power-of-two multiple of the divisor that leaves bit 14 set (since bit 15 is the sign bit; for an unsigned divide you'd want to have bit 15 set instead). bx is that power of 2. If there are limits on the initial value for a you can adjust the initial cx and bx values, but have to be careful because you'll get an incorrect answer if you make them too small.

Upvotes: 3

Antonio Bakula
Antonio Bakula

Reputation: 20693

you can use subtraction and count how many times it take to get to zero, eg. 30/6=5 and 30-6-6-6-6-6=0 so for 30 you must 5 times subtract 6 to get to zero

Something like that:

mov cx,0
mov ax, dividend

divloop:
  cmp ax, 0
  jle done   
  sub ax, divisor
  inc cx
  jmp divloop

done:
  ;result is in cx

Upvotes: 1

Related Questions