2012-04-16 7 views
45

Jestem początkującym w montażu i nie wiem, co oznaczają wszystkie db, dw, dd, rzeczy. Próbowałem napisać ten mały skrypt, który robi 1 + 1, przechowuje go w zmiennej, a następnie wyświetla wynik. Oto mój kod do tej pory:x86 assembly - Który zmienny rozmiar użyć (db, dw, dd)?

.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 

muszę zrozumieć, co db, DW, DD rzeczy, myśli i jak wpływają one na zmienne ustawienie i łączenie i tego typu rzeczy.

Dzięki z góry, Progrmr

+2

bajt db, 8 bitów, dw słowo 16 bitów, dd podwójne słowo 32 bitów. Zauważ, że jest to dla x86 na innych platformach słowo to 32 bity, a pół słowa to 16 bitów. Inne bajty to 9 bitów itd. To, co tworzysz za pomocą db, to zbiór bajtów. tak jak unsigned char [] = ... w C. –

+0

'push eax' /' pop [num] 'jest śmieszne. Po prostu "mov [num], eax". Lub 'mov dword [num], 1 + 1', aby pozwolić asemblerowi zrobić 1 + 1 dla ciebie w czasie składania, zamiast wykonywania, i emitować kodowanie instrukcji' mov m32, imm32'. (Rozmiar 'dword' jest potrzebny, ponieważ nie istnieje operand rejestru, z którego można wywnioskować rozmiar). Lub 'mov eax, 1' /' add eax, 1'. –

+0

Przyjmuję z liczby przegranych, że jest to jedno z tych pytań RTFM, które pojawiają się wyżej w google niż rzeczywisty podręcznik.** Zobacz [wiki tagu x86] (http://stackoverflow.com/tags/x86/info) ** dla odnośników do materiałów referencyjnych i samouczków. Jedna subtelność nie wymieniona w odpowiedziach jest taka, że ​​MASM używa wielkości przestrzeni zadeklarowanej po etykiecie, aby implikować wielkość instrukcji odnoszących się do niego. Składnia NASM nie ma żadnego dziwnego przypuszczenia - o tym, co masz na myśli - możesz powiedzieć, w jaki sposób instrukcja zostanie zebrana bez patrzenia na inne linie źródłowe. –

Odpowiedz

59

Szybki przegląd,

  • DB - Określ bajt. 8 bitów
  • DW - Zdefiniuj słowo. Ogólnie 2 bajty na typowym 32-bitowym systemie x86
  • DD - Zdefiniuj podwójne słowo. Ogólnie 4 bajty na systemie 32-bitowym typowy x86

Od x86 assembly tutorial,

Dyspozycja pop usuwa element danych 4-bajtowy z wierzchu się sprzętowo obsługiwane stos Into the określony operand (tj. rejestr lub lokalizacja pamięci). Najpierw porusza 4 bajty zlokalizowane w miejscu pamięci [SP] w określonej lokalizacji do rejestru lub pamięci, a następnie zwiększa SP przez 4.

Twój num 1 bajt. Spróbuj zadeklarować go przy pomocy DD, aby stał się 4 bajtami i pasował do semantyki pop.

+2

Dzięki. To było bardzo pomocne! – Progrmr

20

Pełna lista to:

DB, DW, DD, DQ, DT, DDQ, a nie

See (służy do deklarowania danych zainicjowany w pliku wyjściowym.): http://www.tortall.net/projects/yasm/manual/html/nasm-pseudop.html

mogą one być powoływane w szerokim zakresie sposobów: (Uwaga: Visual-Studio - korzystaj z „h” zamiast „0x” składni - np: nie 0x55 ale 55h zamiast):

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 nie akceptuje numeryczne c onstants jako operandy, a DDQ nie przyjmuje stałych zmiennoprzecinkowych jako operandów. Dowolny rozmiar większy niż DD nie przyjmuje łańcuchów jako operandów.

+0

hmm, jak np. @LeoMingo wskazał w swoim komentarzu (opublikowanym jako odpowiedź), ten przykład jest błędny! Łańcuchy powinny być dużymi literami, aby podać te wartości ASCII. Małe wartości ascii mają wartości szesnastkowe większe o 0x20. –

+0

Dobrze zauważony! Naprawiłem to. – cnd