在x86汇编中使用哪个可变大小(db,dw,dd)?


72

我是汇编的初学者,我不知道所有db,dw,dd的含义是什么。我试图编写一个执行1 + 1的小脚本,将其存储在变量中,然后显示结果。到目前为止,这是我的代码:

.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

我需要了解db,dw,dd的含义,以及它们如何影响变量设置和组合以及类似的事情。

在此先感谢,Progrmr


2
db字节,8位,dw字16位,dd双字32位。请注意,这是针对其他平台上的x86,一个字为32位,而半字为16位。其他字节是9位,以此类推。用db创建的是字节的集合。就像无符号字符[] = ...中C.
old_timer

push eax/pop [num]很荒谬。只是mov [num], eax。或者mov dword [num], 1+1让汇编器在汇编时而不是在运行时为您执行1 + 1,并发出mov m32, imm32指令编码。(dword需要大小,因为没有寄存器操作数可以从中推断大小)。或mov eax, 1/ add eax, 1
彼得·科德斯

从投票数来看,我认为这是Google提出的RTFM问题之一,高于实际手册。 请参阅x86标签Wiki,以获取参考资料和教程的链接。答案中未提及的一个细微之处是,MASM使用在标签后声明的空间大小来暗示引用该空间的指令的操作数大小。NASM语法没有任何奇怪的猜测(意味着什么),您可以在不查看其他源代码的情况下,知道指令的汇编方式。
彼得·科德斯

Answers:


97

快速复审,

  • DB-定义字节。8位
  • DW-定义字。在典型的x86 32位系统上通常为2个字节
  • DD-定义双字。在典型的x86 32位系统上通常为4个字节

x86汇编教程开始

pop指令将4字节数据元素从硬件支持的堆栈的顶部移至指定的操作数(即寄存器或内存位置)。它首先将位于内存位置[SP]的4个字节移至指定的寄存器或内存位置,然后将SP递增4。

您的num是1个字节。尝试使用声明它DD,使其变为4字节并与pop语义匹配。


2
谢谢。这非常有帮助!
Progrmr 2012年

“位于内存位置[SP]”-仅对16位堆栈正确。在x86系统上,堆栈通常为32位,使用寻址esp。(当然rsp是x86-64。)
ecm

31

完整列表是:

DB,DW,DD,DQ,DT,DDQ和DO(用于在输出文件中声明初始化的数据。)

请参阅:http : //www.tortall.net/projects/yasm/manual/html/nasm-pseudop.html

它们可以通过多种方式调用:(注意:对于Visual Studio,请使用“ h”而不是“ 0x”语法-例如:不是0x55,而是55h):

    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不接受数字常量作为操作数,而DDQ不接受浮点常量作为操作数。任何大于DD的大小都不能接受字符串作为操作数。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.