How can I move two dword into one qword?

2019-07-27 05:23发布

问题:

I found similiar anwser here, but it works only for 32bit. How can I do it in NASM in 64bit processor?

回答1:

Assuming this is X86, just put the low order dword first, high order dword second. I'm not sure about nasm, but for masm:

        .data
myqwrd  dd     089abcdefh, 001234567h         ;0123456789abcdef low first
; ...
        .code
        mov     eax, qword ptr myqwrd
;       or for immediate store
        mov     qword ptr myqwrd, 0fedcba9876543210h
;       or from ebx (low), ecx (high)
        mov     edx,ecx
        shl     rdx,32
        mov     eax,ebx
        or      rax,rdx


回答2:

You can use two double-word consecutive variables (one after another), assign them values separatedly, then get both values as one quad-word. I tested next code in this online compiler :

section .data
    dw1  : dd 0   ;◄■■ FIRST DOUBLE-WORD.
    dw2  : dd 0   ;◄■■ SECOND DOUBLE-WORD.

section .text
    global _start
_start:

    mov dword [dw2], 12345678h   ;◄■■ ONE DOUBLE-WORD.
    mov dword [dw1], 90ABCDEFh   ;◄■■ ANOTHER DOUBLE-WORD.
    mov rax, [dw1]               ;◄■■ GET ONE QUAD-WORD (1234567890ABCDEFh).

Notice how the second double-word (dw2) gets the higher value, and the first double-word (dw1) gets the lower value. Also notice how the quad-word is extracted from the first variable but it reaches the second variable because of the size of rax.

Previous code doesn't display anything to know what is going on in RAX, so this is my original code: it moves the value from RAX into a string, then displays the string (garbage chars) :

section .data
    str1 : db  '12345678',10
    len  : equ $-str1
    dw1  : dd 0
    dw2  : dd 0

section .text
    global _start
_start:
    mov eax, 4
    mov ebx, 1
    mov ecx, str1
    mov edx, len
    int 80h             ;◄■■ DISPLAY STRING = "12345678".

    mov rax, 01234567890ABCDEFh ;◄■■ MOVE ONE QUAD-WORD DIRECTLY.
    mov [str1], rax    
    mov eax, 4
    mov ebx, 1
    mov ecx, str1
    mov edx, len
    int 80h             ;◄■■ DISPLAY STRING = "�ͫ�xV4"

    mov dword [dw2], 12345678h ;◄■■ MOVE ONE DOUBLE-WORD.
    mov dword [dw1], 90ABCDEFh ;◄■■ MOVE ANOTHER DOUBLE-WORD.
    mov rax, [dw1]
    mov [str1], rax    
    mov eax, 4
    mov ebx, 1
    mov ecx, str1
    mov edx, len
    int 80h            ;◄■■ DISPLAY STRING = "�ͫ�xV4" AGAIN!!!

    mov eax,1
    mov ebx,0
    int 80h

EDIT : previous is the "int 80h" version, next is the "syscall version" (thanks @MichaelPetch for telling me what registers I had to use), also tested in the same online compiler :

section .data
    str1 : db  '12345678',10
    len  : equ $-str1
    dw1  : dd 0
    dw2  : dd 0

section .text
    global _start
_start:
    mov rax, 1
    mov rdi, 1
    mov rsi, str1
    mov rdx, len
    syscall             ;◄■■ DISPLAY STRING = "12345678".

    mov rax, 01234567890ABCDEFh ;◄■■ MOVE ONE QUAD-WORD DIRECTLY.
    mov [str1], rax    
    mov rax, 1
    mov rdi, 1
    mov rsi, str1
    mov rdx, len
    syscall             ;◄■■ DISPLAY STRING = "�ͫ�xV4"

    mov dword [dw2], 12345678h ;◄■■ MOVE ONE DOUBLE-WORD.
    mov dword [dw1], 90ABCDEFh ;◄■■ MOVE ANOTHER DOUBLE-WORD.
    mov rax, [dw1]
    mov [str1], rax    
    mov rax, 1
    mov rdi, 1
    mov rsi, str1
    mov rdx, len
    syscall            ;◄■■ DISPLAY STRING = "�ͫ�xV4" AGAIN!!!

    mov rax,60
    mov rdi,0
    syscall


标签: assembly nasm