【发布时间】:2020-03-30 12:39:56
【问题描述】:
我正在尝试以 MB 为单位逐行输出从 byte 到 real10 的几乎所有数据类型的小数(整数和浮点数),但由于某种原因,几乎没有一个可以正确显示(下图),大多数它们坏了,有人可以解释为什么会这样吗?我的错误是什么?
.386
.model flat, stdcall
option casemap: none
include \masm32\include\masm32rt.inc
.data
titletext db 'Title',0
frmt db 'A (Byte) = %d',10
db '-A (Byte) = %d',10
db 'A (Word) = %d',10
db 'B (Word) = %d',10
db '-A (Word) = %d',10
db '-B (Word) = %d',10
db 'A (ShortInt) = %d',10
db 'B (ShortInt) = %d',10
db 'C (ShortInt) = %d',10
db '-A (ShortInt) = %d',10
db '-B (ShortInt) = %d',10
db '-C (ShortInt) = %d',10
db 'A (LongInt) = %d',10
db 'B (LongInt) = %d',10
db 'C (LongInt) = %d',10
db '-A (LongInt) = %d',10
db '-B (LongInt) = %d',10
db '-C (LongInt) = %d',10
db 'D (Single) = %g',10
db '-D (Single) = %g',10
db 'E (Double) = %g',10
db '-E (Double) = %g',10
db 'F (Extended) = %g',10
db '-F (Extended) = %g',0
buff db 1024 dup (?)
Abyte db 6
nAbyte db -6
Aword dw 6
Bword dw 603
nAword dw -6
nBword dw -603
Ashort dd 6
Bshort dd 603
Cshort dd 6032000
nAshort dd -6
nBshort dd -603
nCshort dd -6032000
Along dq 6
Blong dq 603
Clong dq 6032000
nAlong dq -6
nBlong dq -603
nClong dq -6032000
Dsingle real4 0.001
nDsingle real4 -0.001
Edouble real8 0.074
nEdouble real8 -0.074
Fextended real10 735.430
nFextended real10 -735.430
.code
start:
invoke crt_sprintf, addr buff, addr frmt,
Abyte, nAbyte,
Aword, Bword, nAword, nBword,
Ashort, Bshort, Cshort, nAshort,nBshort, nCshort,
Along, Blong, Clong, nAlong, nBlong, nClong,
Dsingle, nDsingle,
Edouble, nEdouble,
Fextended, nFextended
invoke MessageBox, 0, addr buff, addr titletext, MB_OK
invoke ExitProcess, 0
end start
当前结果:
【问题讨论】:
-
您正在使用
%d转换来转换您未提升为int的窄参数。如果 MASM 的invoke没有为您神奇地对它们进行签名或零扩展,它们可能包含大量垃圾。此外,short通常是 16 位字节,但您使用的是dd。在这种情况下,这无关紧要,因为 32 位代码总是至少使用 32 位堆栈槽来传递参数。说到这一点,看看invoke是如何组装的,然后看看它做了什么之后的堆栈内存,看看你的 args 是否被正确传递。 -
此外,浮点数都被破坏了,因为您忘记将浮点的 C 默认提升应用到双倍,这对于 args 总是发生在可变参数函数的
...部分。 How to print a single-precision float with printf。因此,您的 4 字节浮点数稍后会扭曲所有内容。 -
哦,同样,您有一些
dq64 位整数,但您仍然告诉 sprintf 它们是%dint。 -
@PeterCordes 谢谢!还想问一下您通常需要多少缓冲区?
-
@PeterCordes 我已将所有
byte、word和dword更改为签名类型并且效果很好,但我遇到了qword和real4的问题。我将%d更改为%ld为qword,但它仍然将0放在下一个条目中,并将所有数字移到它之后。关于浮点数,正如我从您发布的另一个线程的链接中了解到的那样 - 无法打印出浮点数,我需要以某种方式将其转换为不同的类型?对不起,如果我理解不好。
标签: assembly x86 printf masm masm32