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