Solved

# Assembly Language division without using DIV HELP

Posted on 2006-04-18
1,113 Views
I have a homework assignment that I understand the theory behind but do not know how to write it in assembly.  The program must perform integer division that the user inputs, without using DIV.
It must use this alogorithm:
const int MAX_REPS =8;
for (int reps=1; resp <=MAX_REPS; reps++)
{
if (Product (LSB) == 1)
Add multiplicand to the left half of the product and place the result in the left half of the Product register;
Shift the Product register right 1 bit;
}

The dividend and the divisor must be positive and smaller than 65,535.  All inputs are to be validated with a reprompt occurring when there is illegal input.  The program is to prompt for and validate a dividend and a divisor and then display the quotient and the remainder.

This is an extra part I need to do for this assignment:
Allow the user to enter both positive and negative numbers.  You can choose to half the ranges as is done with the Integer type variable in a high level language, or you can choose to keep the same ranges, just allow negatives as well as positives.  It must indicate the range by displaying it at the beginning of the program, so the user can know what test valuses to use.

I know the basic therory of multiplying by 1/10 and then shifting the register, I just dont know how to do it in assembly.  And I have no idea how to do the second part.  Please help
0
Question by:psi3000

LVL 3

Accepted Solution

Well, consult the Intel processor data sheets on available opcodes for arithmetic operations in assembly language. You will need MOV (move data from/to registers or memory locations), SHR and SHL (shift right, shift left), ADD/ADC (Add, Add with carry) etc.
This website is not intended to do your homework, but I know that it is sometimes very difficult to get an initial idea of something. So read up on the instructions mentioned above and try to form your algorithm. I'll answer detail questions and assist you, but I'll not finish your homework ;)
0

LVL 9

Assisted Solution

To give you some assistance:

You can always generate assembly language using a C/C++ compiler - just create a (compilable!) fragment of code and compile with the 'assembly' switch and look at the generated assembly.

If you also optimise the code you may see the DIV optimised away and replaced with equivalent instructions...

Try variations to get different code fragments...

0

LVL 3

Expert Comment

The problem with the approach that gabeso mentioned is that integer divisions will basically always end up as DIV a,b opcodes. I can't think of any compiler switch that would keep the compiler from using the built-in DIV instruction - DIV has been available for ages on the x86 platform and it is always faster than a discrete implementation, even if you unroll the loop used in the pseudo-code posted by psi3000.
Nonetheless, the approach itself is valid for more complex algorithms, just not when the task is to re-implement a CPU opcode :)
0

Author Comment

Yeh, I just have no idea on how to begin this program.
Here is what I have:
.model small
.stack 100h
.data
msg1 db "Enter dividend":
msg2 db "Enter divisor":
msg3 db "Illegal integer":
msg4 db "END OF DATA":
msg5 db "Richard Pulliam CSC242, Section 01 assignment 3":
.code
main proc
mov dx, offset msg5
mov dx, offset msg1
mov ah,9
int 21h
jb error      ;sends user to error subroutine if over 65536
mov al,0AH      ;moves string/dividend into al
int 21h
mov dx, offset msg2
mov ah,9
int 21h
jb error
mov ch,0AH      ;moves string/divisor into ch
int 21
mov bh,ch
nextIteration:             ;called within the loop while bh is 2 or over
shr al,1      ;shifts al to the right one dividing al by 2
sub bh,2      ;subtracting 2 from bh
add cl,1      ;adding 1 to ch to keep track of our product
cmp bh,1      ;compairing bh to 1 to send to one subroutine
jmp one            ;jump if bh equals 1
cmp bh,2      ;compairing bh to 2
jae nextIteration      ;jumping to nextIteration if bh is equal to or above 2
offset cl      ;displaying product which is in cl
mov ah,9
int21
jmp done      ;exiting program

error:            ;subroutine called when input throws jb flag to make sure input is not over the 65536 barrier
mov dx, offset msg3

one:            ;subroutine called when bh is equal to one
sub al,ch      ;subtracting ch since it is our original divisor because we can only divide by 2
offset cl
mov ah,9
int21

done:
mov dx, offset msg4

exit

Ok this is what I have does it look ok.  Does it make sence. i dont even know how I came up with it. Could be completely wrong.  But hopfully someone can show me what I am doing wrong and can understand by it what I want to do.
thanks guys
0

Author Comment

Ok I found some errors while compiling. Here is my new program:
.model small
.stack 100h
.data
msg1 db "Enter dividend":
msg2 db "Enter divisor":
msg3 db "Illegal integer":
msg4 db "END OF DATA":
msg5 db "Richard Pulliam CSC242, Section 01 assignment 3":
.code
main proc
mov dx, offset msg5
mov ah,9
int 21h
mov dx, offset msg1
mov ah,9
int 21h
jb error      ;sends user to error subroutine if over 65536
mov al,0AH      ;moves string/dividend into al
int 21h
mov dx, offset msg2
mov ah,9
int 21h
jb error
mov ch,0AH      ;moves string/divisor into ch
int 21
mov bh,ch
nextIteration:             ;called within the loop while bh is 2 or over
shr al,1      ;shifts al to the right one dividing al by 2
sub bh,2      ;subtracting 2 from bh
add cl,1      ;adding 1 to ch to keep track of our product
cmp bh,1      ;compairing bh to 1 to send to one subroutine
jmp one            ;jump if bh equals 1
cmp bh,2      ;compairing bh to 2
jae nextIteration      ;jumping to nextIteration if bh is equal to or above 2
mov dx, offset cl      ;displaying product which is in cl
jmp done      ;exiting program

error:            ;subroutine called when input throws jb flag to make sure input is not over the 65536 barrier
mov dx, offset msg3
mov ah,9
int 21h

one:            ;subroutine called when bh is equal to one
sub al,ch      ;subtracting ch since it is our original divisor because we can only divide by 2
mov d, offset cl

done:
mov dx, offset msg4

end main

I have an compiling error it says : "fatal error A1010: unmatched block nesting : main" can anyone help with this as well.
thanks
0

LVL 3

Expert Comment

The copy and paste was incomplete but apart from that... "I don't even know how I came up with it" smells like google plus copy & paste ;) This can prove to be a dangerous thing sometimes ;) You should at least understand what you copy and paste :)

But back to the code. I have a couple of hints for you:

- bl, bh, cl, ch are 8-bit registers. You are dealing with numbers up to 65535, does that ring a bell? If so, what changes are required in the code?
- The beginning of main proc lacks some instructions right at the beginning. Do you know which ones?
0

LVL 3

Expert Comment

Okay, your post and mine overlapped so clear for next round :)

You found the missing text output, but you messed up with the text input. I recommend consulting Ralf Brown's interrupt list for requirements for your int21 calls. And you should pay attention to which registers are set to what values for particular functions.
Here is a great HTML version of that interrupt list: http://www.ctyme.com/rbrown.htm

Looking at Int21h/AX=000Ah says you need to prepare the buffer with some data before calling that function. I am sure you can add the necessary code to your program without my help ;)

Then the end of your main routine (see labels done, one, error) looks a bit bad to me. To terminate your DOS program, you have to call the proper DOS function. You can find it in the interrupt list as well.

The code after the label "error" should terminate the program too, so that it can't proceed with the instructions following the labels "one" and "done".

The code after "one" looks suspicious, too. What exactly should it do?

About the compiling error you get: which assembler do you use?
0

LVL 3

Expert Comment

Oh, one thing: Try to enter a number over 65535, you'll notice that it doesn't complain about it. Do you see why?
0

Author Comment

Ok first of all, no, this is not a copy and paste from any place at all.  I came up with this on my own, I promise you that. And I used ML, does that sound familar, or MASM?  I have no idea what you are talking about with that HTML, there is just a bunch of links to interupt lists.  Which one do I need?  And how did you get it to work if you entered a number over the 65535 barrier? I cant even get mine to compile still
0

LVL 3

Expert Comment

About the interrupt list: You're already using functions from interrupt 21h, so you may have figured that it would make sense to look at the other functions offered by that interrupt. First things first, let's solve that compilation error.

PROC and END don't match, if you start a block of code with PROC you need to end it with ENDP. But in your sample problem there is just one procedure, the main one so just leave out PROC :)

Then, understand what you are doing at all. You are using Int21h/AX=000Ah to collect user input. This function needs a pointer to a reserved and prepared buffer for input. The "bunch of links to interrupt lists" can be used to find out what's missing to prepare the buffer properly. Otherwise your program will do all kinds of crazy stuff including crashes and spontaneous reboots. Trust me, I've been there :)

And of course, checking for the value of the input is absolutely senseless if you check it before you even process it.

Last but not least for this post: Think about what you get when you read input from the user byte by byte. Correct, you'll get a string. You have to convert it to a number before you can use it for calculations...
0

## Featured Post

### Suggested Solutions

sum28 challenge 31 82
has77  challenge 9 58
map interface methods 3 46
Delphi Mdi application Child forms get behind control 7 76
This article is meant to give a basic understanding of how to use R Sweave as a way to merge LaTeX and R code seamlessly into one presentable document.
In this post we will learn how to connect and configure Android Device (Smartphone etc.) with Android Studio. After that we will run a simple Hello World Program.
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …
In this fifth video of the Xpdf series, we discuss and demonstrate the PDFdetach utility, which is able to list and, more importantly, extract attachments that are embedded in PDF files. It does this via a command line interface, making it suitable …