87

I don't know what all the db, dw, dd, things mean. I have tried to write this little script that does 1+1, stores it in a variable and then displays the result. Here is my code so far:

.386
.model flat, stdcall 
option casemap :none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\masm32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\masm32.lib
.data
num db ? ; set variable . Here is where I don't know what data type to use.
.code
start:
mov eax, 1               ; add 1 to eax register
mov ebx, 1               ; add 1 to ebx register
add eax, ebx             ; add registers eax and ebx
push eax                 ; push eax into the stack
pop num                  ; pop eax into the variable num (when I tried it, it gave me an error, i think  thats because of the data type)
invoke StdOut, addr num  ; display num on the console.
invoke ExitProcess       ; exit
end start

I need to understand what the db, dw, dd things mean and how they affect variable setting and combining and that sort of thing.

starball
  • 20,030
  • 7
  • 43
  • 238
Progrmr
  • 1,575
  • 4
  • 26
  • 44
  • 4
    db byte, 8 bits, dw word 16 bits, dd double word 32 bits. Note this is for x86 on other platforms a word is 32 bits and halfword is 16 bits. Others a byte is 9 bits, etc. What you are creating with a db is a collection of bytes. just like unsigned char[]=... in C. – old_timer Apr 16 '12 at 04:40
  • `push eax` / `pop [num]` is ridiculous. Just `mov [num], eax`. Or `mov dword [num], 1+1` to let the assembler do the 1+1 for you at assemble time, instead of run-time, and emit an `mov m32, imm32` instruction encoding. (The `dword` size is needed because there's no register operand to infer the size from). Or `mov eax, 1` / `add eax, 1`. – Peter Cordes Feb 25 '16 at 10:07
  • 2
    I assume from the number of upvotes that this is one of those RTFM questions that comes up higher in google than the actual manual. **See [the x86 tag wiki](http://stackoverflow.com/tags/x86/info)** for links to reference material and tutorials. One subtlety not mentioned in the answers is that MASM uses the size of the space declared after a label to imply the operand-size of instructions that refer to it. NASM syntax doesn't have any weird guess-what-you-mean stuff going on: you can tell how an instruction will assemble without looking at other lines of source. – Peter Cordes Feb 25 '16 at 10:16
  • 1
    Which one you use depends on what you need to do. For ASCII strings, use `db`. For pointers, use `dd` on 32-bit hardware (`dq` on 64-bit hardware). Most often you're going to be using `dd` since you're using `.386` as your CPU. But there are moments where you're going to want to use other types. Keep in mind that there is no enforcement of type rules in assembly at all. So the assembler won't stop you from loading data as the wrong type like a C compiler would. – puppydrum64 Dec 07 '22 at 18:17

2 Answers2

118

Quick review,

  • DB - Define Byte. 8 bits
  • DW - Define Word. Generally 2 bytes on a typical x86 32-bit system
  • DD - Define double word. Generally 4 bytes on a typical x86 32-bit system

From x86 assembly tutorial,

The pop instruction removes the 4-byte data element from the top of the hardware-supported stack into the specified operand (i.e. register or memory location). It first moves the 4 bytes located at memory location [SP] into the specified register or memory location, and then increments SP by 4.

Your num is 1 byte. Try declaring it with DD so that it becomes 4 bytes and matches with pop semantics.

Evan Carroll
  • 78,363
  • 46
  • 261
  • 468
Pavan Manjunath
  • 27,404
  • 12
  • 99
  • 125
  • 1
    "located at memory location [SP]" -- This is only correct for 16-bit stacks. On x86 systems the stack is generally 32-bit, addressed using `esp`. (And of course `rsp` for x86-64.) – ecm Sep 30 '20 at 16:22
  • `DQ` - define 8 bytes (64 bits) – SurfaceStack Jul 12 '23 at 10:15
38

The full list is:

DB, DW, DD, DQ, DT, DDQ, and DO (used to declare initialized data in the output file.)

See: http://www.tortall.net/projects/yasm/manual/html/nasm-pseudop.html

They can be invoked in a wide range of ways: (Note: for Visual-Studio - use "h" instead of "0x" syntax - eg: not 0x55 but 55h instead):

    db      0x55                ; just the byte 0x55
    db      0x55,0x56,0x57      ; three bytes in succession
    db      'a',0x55            ; character constants are OK
    db      'hello',13,10,'$'   ; so are string constants
    dw      0x1234              ; 0x34 0x12
    dw      'A'                 ; 0x41 0x00 (it's just a number)
    dw      'AB'                ; 0x41 0x42 (character constant)
    dw      'ABC'               ; 0x41 0x42 0x43 0x00 (string)
    dd      0x12345678          ; 0x78 0x56 0x34 0x12
    dq      0x1122334455667788  ; 0x88 0x77 0x66 0x55 0x44 0x33 0x22 0x11
    ddq     0x112233445566778899aabbccddeeff00
    ; 0x00 0xff 0xee 0xdd 0xcc 0xbb 0xaa 0x99
    ; 0x88 0x77 0x66 0x55 0x44 0x33 0x22 0x11
    do      0x112233445566778899aabbccddeeff00 ; same as previous
    dd      1.234567e20         ; floating-point constant
    dq      1.234567e20         ; double-precision float
    dt      1.234567e20         ; extended-precision float

DT does not accept numeric constants as operands, and DDQ does not accept float constants as operands. Any size larger than DD does not accept strings as operands.

Mafii
  • 7,227
  • 1
  • 35
  • 55
cnd
  • 1,689
  • 16
  • 14