News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Division and the relationship with registers

Started by Jbarrera, February 18, 2018, 03:45:16 PM

Previous topic - Next topic

Jbarrera

Hello all,

I know that this may be trivial to many programmers on here and I do apologize. I am just having some trouble understanding the relationship between the registers and division.

currently, I am working on a piece of code that will convert a numeric value into an ASCII character to be displayed on the screen.

I have a general idea of how to do it. The steps I plan to take are the following

1. Take the number I plan to convert to ascii and divide it by ten
2. take the remainder and save it to an array (keep doing this until the whole number is in the array - backwards most likely)
3. add the numbers in the array by the ascii char for '0 to convert it to the numerical representation of "said" number.
4. print them out backwards from the array to put them back in order
5. use a write routine to print out the values to screen.

So an example:

;other important stuff

.data

    PutDataHere  byte      8 dup(?)
    val1            word     356
    divisor          byte      10
    temp         byte      ?    ;same problem is I use word

.code

mov ax, val1
mov bl,divisor
idiv bl
lea esi, PutDataHere
mov [esi],AH
inc esi
mov temp,AL
mov ax, temp ;datasize conflict


main PROC



main END

END main


So my questions:

1. does dividing ax always result with the answer in AL and AH, where AH is the remainder
2. what about dividing EAX or AH, do they always default to the same registers, or how is that determined.
3. How can I keep dividing a value to keep splitting it up
        - in the above example, I want to divide 356 by 10 to get 35.6 and save the six, I then want to loop back and divide 35 by 10 to get 3.5 and save the 5 then finally 3/10 to get .3  and save the 3.

I understand that a 16-bit number once divided will result in an 8-bit answer and remainder, so how can I take the 8-bit answer and divide it again without having a size conflict.

Once again this may be very simple for some, but I am a very visual learner and sometimes I need things explained like a 5th grader :(

thank you.


aw27

#1
1- See my example below
2- Better you check the Intel manual or use Google, there are some variations.
3- You need a LIFO container like a stack or you can use recursion. There are many examples in this forum, but better you search for yourself and learn in the process. A posteriori, I made an example (below).

LordAdef

Hey, why not do the divisions with dword instead. I would do something like this:

.data
cc dd 12345678

.code
start:

mov eax, cc
mov ecx, 10

next:
cdq
div ecx
; your digit is in edx
test eax, eax
jnz next

exit
end start


the rest is easier with byte ptr edx

ps: Maybe the gurus around have a better idea, but this looks straight forward to me :biggrin:

aw27

Example for word:


.386
.model flat, stdcall

includelib \masm32\lib\msvcrt.lib
printf proto C, : vararg

.data
mynum dw 61245
result db 6 dup (0)

.code

main proc
xor ecx, ecx
xor eax, eax

mov ebx, 10
mov ax, mynum

other:
xor edx, edx
inc ecx
div bx
push edx
cmp ax, 0
jnz other

lea edi, result
toascii:
pop eax
or al, 30h
stosb
loop toascii

lea eax, result
push eax
call printf
add esp, 4
ret
main endp

end



daydreamer

Quote from: LordAdef on February 18, 2018, 06:38:40 PM
Hey, why not do the divisions with dword instead. I would do something like this:
ps: Maybe the gurus around have a better idea, but this looks straight forward to me :biggrin:
http://www.ray.masmcode.com/
look here on loads of information, check BCD link
check his fpu tutorial, which already has instructions for packed BCD conversion
http://www.ray.masmcode.com/tutorial/fpuchap6.htm
packed means its get stored, like dw 56, gets stored in each byte $56 hexadecimal, in nibbles
check his fixed Point math also
my none asm creations
https://masm32.com/board/index.php?topic=6937.msg74303#msg74303
I am an Invoker
"An Invoker is a mage who specializes in the manipulation of raw and elemental energies."
Like SIMD coding

LordAdef

Quote from: daydreamer on February 18, 2018, 10:54:13 PM
Quote from: LordAdef on February 18, 2018, 06:38:40 PM
Hey, why not do the divisions with dword instead. I would do something like this:
ps: Maybe the gurus around have a better idea, but this looks straight forward to me :biggrin:
http://www.ray.masmcode.com/
look here on loads of information, check BCD link
check his fpu tutorial, which already has instructions for packed BCD conversion
http://www.ray.masmcode.com/tutorial/fpuchap6.htm
packed means its get stored, like dw 56, gets stored in each byte $56 hexadecimal, in nibbles
check his fixed Point math also

But.. this is not what he wants DayDreamer. He doesn´t need fpu, he wants to isolate the digits of a bigger number. This is exactly what my snipet does, and if he wanted to work with word size, aw27 gave a nice algo too

jj2007

Quote from: LordAdef on February 19, 2018, 08:23:35 AMhe wants to isolate the digits of a bigger number. This is exactly what my snipet does

Your snippet, marginally enriched for copy, paste, build & run:include \masm32\include\masm32rt.inc

.data
cc dd 12345678

.code
start:

mov eax, cc
mov ecx, 10

next:
  cdq
  div ecx
  pushad
  print str$(edx), " " ; your digit is in edx
  popad
  test eax, eax
jnz next

exit
end start

aw27

I still prefer not to print the digits backwards. Of course, I can use a mirror.  ;)

Jbarrera

 aw27 that piece of code really helped me understand it better. It was way easier to just use dword. I'm going to start doing decimals soon so those links daydreamer put up are useful.
Thanks for the help everyone.

LordAdef

Nice jBarrera! :eusa_dance:

Remember one thing. You may want to save your digits into an array for future manipulation.

This way you can add them in the order of your preference :eusa_dance:

I'm not sure if you understood aw27 method: he pushed the values and them pop. This method inverts the order because it's "first in last out" in the stack.

JJ printed edx to console. He used pushad popad to save the registers that will be trashed by the "print" stuff. That's why they are there encapsulating the print line (try it without pushad popad, it's fun :eusa_naughty:)

Sorry if you already know all this, just trying to help, I've been there too

LordAdef

Quote from: Jbarrera on February 19, 2018, 10:24:54 PM
aw27 that piece of code really helped me understand it better. It was way easier to just use dword. I'm going to start doing decimals soon so those links daydreamer put up are useful.
Thanks for the help everyone.

DayDreamer's link is the best tutorial for fpu. Raymond is a very clear writer.

One suggestion if I may: I don't know about your needs or plans, but I would stay away from fpu for a while until you get comfortable with everything else. There is a lot you can do without it, and a lot to learn before.

Well, at least this was my approach, and I don't regret it.

I hope that helps

felipe

I think in general that if you are young, you have time, etc. you can try it all. Then, if you have the taste for it, probably you will start to dig in specific issues. As time goes by, the big picture will show up...

:icon14: