Re: itoa assembly version



leon800219@xxxxxxxxx wrote:
Frank Kotler <characters my browser doesn't like :)>


"div bx" divides dx:ax by bx, not just ax. If the result won't fit in
ax, which it won't if dx>=bx, it causes an exception.

Most common newbie error in existance!

I have set the dx to zero before divide operation. So "div bx" turn out
to be divide 0000:ax by bx. And I figure that will not cause any
"divide overflow"

And the code changed to:

assume cs:code,ds:data

data segment
dw 12, 23, 34, 45, 56, 12666
data ends
display segment
db '000000000000000', 0
display ends

stack segment
db '0000000000'
stack ends

code segment

start:

mov ax, data
mov es, ax
mov ax, display
mov ds, ax
call dtoc

mov si, 0
mov dh, 8
mov dl, 3
mov cl, 2
call show_str

mov ax,4c00h
int 21h
dtoc:
mov di, 0
mov cx, 6
s:
push cx
mov ax, es:[di]
mov bx, 0AH
s0: div bx
mov cx, ax
jcxz ok
add dl, 30h
mov byte ptr ds:[si], dl
mov dx, 0
inc si
jmp short s0

ok:add dl, 30h
mov byte ptr ds:[si], dl
inc si
add di, 2
mov dx, 0
pop cx
loop s
ret

I have debugged it in protected mode and found that
ds:0 contains 213243546566621 which is quite what I want, though in
reverse order, I could use stack to implement that. But the question is
when I run this program in real mode(because I want it to displayon
screen), I still experience "divide overflow", how this could be?

The only thing I see (without testing it) is that you zero dx at the *end* of your loop. What's dx on the *first* iteration? Possibly different in "protected mode" - I assume you mean v86 mode - and real mode? That's what first comes to mind... try moving it and see if it helps.

What's the advantage of moving ax to cx and then testing cx for zero, compared to just testing ax for zero?

You'd have a more "reuseable" subroutine if you called it six times, rather than hard-coding "six numbers" into the subroutine. Your method of using a separate segment for the output buffer, and hard-coding offset 0 for source and destination is ... uhhh... unusual - and not very "maintainable". Your stack seems awfully small - remember that interrupts use your stack (in rmode - in pmode, they usually switch stacks), in addition to any use your code makes of it. I'd go with a minimum of 256 bytes or so. (you're getting 16 bytes anyway, I suspect, but why make it so small?)

Well, that's enough complaints. :) You've got it "sorta working" so far... now you need to reverse the order. You could use the stack (if it's big enough) as you suggest. You could start at the "end" of the buffer, and decrement the pointer as you go... this could leave "garbage" in front of the string, if you're not careful - but works well if you want your numbers "right justified", which looks a lot better if you're printing a column of numbers. Or you could provide a "reverse string" function which exchanges the first character with the last, then second char with next to last, until it comes to the middle. I like the stack method, myself... You'll want to either count the number of characters pushed, or push a "guard" value first, and watch for it in your "pop loop". I usually use the "count" method, but since you're already using cx, the "guard" method might be better. Your "print" routine apparently expects a zero-terminated string, so zero might make a good guard value. If you were using int 21h/9, you could use '$' conveniently... Using zero means you'll have to do the conversion from number to ascii digit *before* pushing it...

Well, you're closing in on it. As Betov says - one time I do agree with him - "Courage!"

Best,
Frank
.



Relevant Pages

  • Re: Expand Down Stack in Protected Mode
    ... and you start "already below limit" when using expand down! ... Stack will always grow downwards on x86 CPUs. ... and an Expand Down segment can be enlarged downward ... I just needed to change the 'mov dword esp,0x00000010' ...
    (comp.lang.asm.x86)
  • Re: COM/EXE header problem
    ... some header for example. ... mov ax,0x4c00 ... I would expect a linker to warn about "no stack" and "no entrypoint". ... The first "stack" is just a name - could be "segment frank stack" just as easily - but the second "stack" is a segment "attribute", ...
    (alt.lang.asm)
  • Re: Program abnormally terminates
    ... mov ax, DATEN2 ... fiddle and diddle around long enough so an interrupt *will* occur. ... interrupts are "faked" and may get a new stack as you describe... ... 32-bit segment, which we wouldn't want. ...
    (alt.lang.asm)
  • Re: Accessing Command-line text
    ... PROC belongs to HLL. ... that happens very rarly, poluting the stack as you call it, doesnt seem to ... mov eax true ... (A region, inside, is an array of rectangles). ...
    (alt.lang.asm)
  • Re: further optimizations
    ... mov al B$edx;ok ... The users stack is not affected with this, ... but everything below ESP is never usable anyway... ... It had reprogrammed what you call IDT (interrupt table?) and after ...
    (alt.lang.asm)