How are dw and dd different from db directives for strings?

左心房为你撑大大i 提交于 2019-11-28 06:26:32

问题


Let's say I want to define a initialized variable string before running my assembly program (in section .data). The variable I chose to create is called Digits and it is a string that contains all the hexadecimal symbols.

Digits: db "0123456789ABCDEF"

I defined the variable with db, that means define byte. Does this mean that the Digits variable is of 8-bits long? This doesn't seem to have sense for me because:

Each character in the string is an ASCII character, therefore I will need 2 bytes for each character. In total, I would need 32 bytes for the whole string!

So what does it mean when I define the variable as byte? Word? Double word? I don't see the difference. Because of my misunderstanding, it seems to be redundant to tell the type of data you need for the string.

PD: This question didn't help me to understand.


回答1:


One of the answers on the linked question has a quote from the NASM manual's examples which does answer your question. As requested, I'll expand on it for all three cases (and correct the lower-case vs. upper-case ASCII encoding error!):

db   'ABCDE'     ; 0x41 0x42 0x43 0x44 0x45                (5 bytes)
dw   'ABCDE'     ; 0x41 0x42 0x43 0x44 0x45 0x00           (6 bytes, 3 words)
dd   'ABCDE'     ; 0x41 0x42 0x43 0x44 0x45 0x00 0x00 0x00 (8 bytes, 2 doublewords)
dq   'ABCDE'     ; 0x41 0x42 0x43 0x44 0x45 0x00 0x00 0x00 (8 bytes, 1 quadword)

So the difference is that it pads out to a multiple of the element size with zeros when you use dd or dw instead of db.

According to @Jose's comment, some assemblers may use a different byte order for dd or dw string constants. In NASM syntax, the string is always stored in memory in the same order it appears in the quoted constant.

You can assemble this with NASM (e.g. into the default flat binary output) and use hexdump -C or something to confirm the byte ordering and amount of padding.


Note that this padding to the element size applies to each comma-separated element. So the seemingly-innocent dd '%lf', 10, 0 actually assembles like this:

;dd   '%lf',    10,        0
db    '%lf',0,  10,0,0,0,  0,0,0,0        ;; equivalent with db

Note the 0 before the newline; if you pass a pointer to this to printf, the C string is just "%lf", terminated by the first 0 byte.

(write system call or fwrite function with an explicit length would print the whole thing, including the 0 bytes, because those functions work on binary data, not C implicit-length strings.)




回答2:


For each character in the string "0123456789ABCDEF" you need just one byte. So, the string will occupy 16 bytes in the memory.

In case of this declaration:

vark db 1

you can make this:

mov [vark],128

and cannot:

mov [vark],1024

but in this case:

vark dw 1

you can.



来源:https://stackoverflow.com/questions/38860174/how-are-dw-and-dd-different-from-db-directives-for-strings

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!