我使用TASM。
我使用this IO.h文件来从控制台输入和输出。以及itoa
和atoi
。
我的程序是:(目的是简单地将20h
复制到2个内存位置并输出两者。)
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
我得到的输出是:
here it is
32
here it is
12851
然而,当我按变量定义(I swap tmp2和num)进行小改动时:
data segment
msg2 db 13, 10, "here it is", 13, 10, 0
tmp dw ?, 0
tmp2 dw ?, 0
num dw ?, 0
data ends
输出结果为:
here it is
32
here it is
32
有人可以解释为什么会这样吗? 第二个输出是我在两种情况下的预期。
p.s:另外,为什么我们必须使用start
标签?我发现它非常奇怪,它扩展了 代码段。没有这个标签,它无法正常工作。
答案 0 :(得分:2)
您链接的io.h
只包含一个调用库中itoa_proc
的宏,因此我们不知道该过程的工作原理。它可能会使用一些额外的空间,因此即使结果(32
)适合2个字节,也可能会覆盖内存位置,从而破坏您的值。请注意,12851
为0x3233
,其内存类似于0x33
,0x32
,它只是32
的ascii表示形式。只是猜测一下,但是itoa
可能首先产生右对齐输出,然后将其移到左边。
阅读文档或源代码(如果有),或者只为输出字符串保留更多空间。我假设对于16位数字,7个字节应该足够:1表示可能的符号,5表示数字,1表示终止0。