psi3000
asked on
Assembly Language division without using DIV HELP
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
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
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
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":
strHeader db 10
.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 dx, offset strHeader
mov al,0AH ;moves string/dividend into al
int 21h
mov dx, offset msg2
mov ah,9
int 21h
jb error
mov dx, offset strHeader
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
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":
strHeader db 10
.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 dx, offset strHeader
mov al,0AH ;moves string/dividend into al
int 21h
mov dx, offset msg2
mov ah,9
int 21h
jb error
mov dx, offset strHeader
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
ASKER
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":
strHeader db 10
.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 dx, offset strHeader
mov al,0AH ;moves string/dividend into al
int 21h
mov dx, offset msg2
mov ah,9
int 21h
jb error
mov dx, offset strHeader
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
.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":
strHeader db 10
.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 dx, offset strHeader
mov al,0AH ;moves string/dividend into al
int 21h
mov dx, offset msg2
mov ah,9
int 21h
jb error
mov dx, offset strHeader
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
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?
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?
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?
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?
Oh, one thing: Try to enter a number over 65535, you'll notice that it doesn't complain about it. Do you see why?
ASKER
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
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...
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...
Nonetheless, the approach itself is valid for more complex algorithms, just not when the task is to re-implement a CPU opcode :)