I use TASM.
I use this IO.h file for input and output from/to the console. And also for itoa
and atoi
.
My program is : (The purpose is to simply copy to 20h
to 2 memory locations and output both.)
include io.h
data segment
msg2 db 13, 10, "here it is", 13, 10, 0
tmp dw ?, 0
num dw ?, 0
tmp2 dw ?, 0
data ends
code segment
assume cs:code, ds:data
start:
;load segments
mov ax, data
mov ds, ax
;store 20h
mov ax, 20h
;copy to both num and tmp2
mov num, ax
mov tmp2, ax
;output
output msg2
; (itoa puts the output-able into destination, "tmp" here)
itoa tmp, tmp2
output tmp
;output
output msg2
itoa tmp, num
output tmp
;return control
mov ax, 4c00h
int 21h
code ends
end start
The output I get is :
here it is
32
here it is
12851
However when I make a small change in order of variable definition ( I swap tmp2 and num ):
data segment
msg2 db 13, 10, "here it is", 13, 10, 0
tmp dw ?, 0
tmp2 dw ?, 0
num dw ?, 0
data ends
The output is :
here it is
32
here it is
32
Can someone explain why this happens? The 2nd output is what I expected in both cases.
p.s : Also, why do we have to use the start
label? I find it extremely strange that it extends out of the code segment. It doesn't work correctly without that label.
The io.h
you linked only contains a macro that calls the itoa_proc
in a library, as such we don't know how that procedure works. It probably uses some extra space, so even through the result (32
) fits into 2 bytes, it may be overwriting following memory locations hence destroying your value. Note that 12851
is 0x3233
which in memory looks like 0x33
, 0x32
which is just the ascii representation of 32
. Just guessing here, but itoa
may be producing right-justified output first, then moving it to the left.
Read the documentation or the source code, if available, or just reserve more space for the output string. I assume for 16 bit numbers 7 bytes should be enough: 1 for possible sign, 5 for the digits, 1 for the terminating zero.