I know this may be a very simple question, but in masm, what is the largest value a TBYTE can hold in hexadecimal? I'm working on a 64-bit system. My textbook says the largest value it can hold in integer is 999,999,999,999,999,999. I tried putting it in a hex converter and it gives me DE0B6B3A763FFFF. I know this is not right because when I try to run a small program with this value, it gives me errors.
Thanks in advance!
Fuz, here is the program that I'm working on. I just have to initialize each variable with the maximum value it can hold based on the data type.
TITLE Initializing all data types to maximum value
INCLUDE Irvine32.inc
.data
bVar BYTE 255
sVar SBYTE 127
wVar WORD 65535
swVar SWORD 32767
dwVar DWORD 4294967295
sdwVar SDWORD 2147483647
fwVar FWORD 281474976710655
qwVar QWORD 18446744073709551615
tbVar TBYTE 1208925819614629174706175 ; This value works, but still not
clear why it works even though
it isn't in hex.
r4Var REAL4 3.40E+38
r8Var REAL8 1.79E+308
r10Var REAL10 1.18E+4932
.code
main PROC
exit
main ENDP
END main
According to the MASM Version 6.1 Programmer's Guide, the TBYTE directive is supposed to be different than all the other data definition directives in that converts decimal integer initializers into the 80-bit packed BCD (binary coded decimal) format used by the FBLD and FBSTP instructions. As fuz's answer explains in more detail the 80-bit packed BCD format is limited to 18-digit decimal integers.
However, no version of MASM I've tested this on, including MASM 6.1d, actually behaves that way. Using a decimal integer an initializer with the TBYTE directive results in the memory allocated being initialized with an 80-bit integer value. That's just like how decimal integers used with BYTE, WORD and DWORD result in 8-bit, 16-bit and 32-bit integer values respectively being used to initialize memory.
So for example consider the following code:
WORD 12345
DWORD 12345
TBYTE 12345
Acording to the documentation this code should result in memory being initialized with the following bytes, shown in hexadecimal:
39 30
39 30 00 00
45 23 01 00 00 00 00 00 00 00
The first two lines using the 16-bit and 32-bit integer representations of 12345, while the last line has this number in the 80-bit packed BCD format.
However MASM 6.1d and every version MASM I've tried up to the latest version included with Visual Studio 2017 assembles the code above into the following bytes:
39 30
39 30 00 00
39 30 00 00 00 00 00 00 00 00
The fact that a decimal number is used with TBYTE makes no difference and the normal integer format is used just like with the other directives.
This means the actual range of the TBYTE directive isn't that of the 80-bit packed BCD representation but that of an 80-bit twos complement integer. So you can use a value from -604462909807314587353088 to 1208925819614629174706175. (Or at least in theory, MASM 6.1d has a bug and doesn't handle the former number correctly. Later versions fix this bug.)
Note that while the 80-bit packed BCD type is supported x86 CPUs, if only by the FBLD and FBSTP instructions, there are no instructions that work with 80-bit integer values. So using TBYTE with integers isn't all the useful unless you're willing to write the 80-bit integer arithmetic code yourself.
Normally the only 80-bit type you'd use is the 80-bit floating-point type. In that case while you can use the TBYTE directive you should use the REAL10 directive instead, and you need to specify your number a floating-point constant with a decimal point. So to initialize a 80-bit memory location with the number 12345 in the 80-bit floating-point format you would use something like this:
REAL10 12345.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With