像这样:
; Before:
; Result is in DX:AX on the form ABCD:EFGH
; EAX = ????EFGH : AX contains EFGH, upper part of EAX has unknown content
; EDX = ????ABCD : DX contains ABCD (the 16 most siginficant bits
; of the multiplication result)
; like with EAX the upper (=most siginifcant)
; 16 bits of EDX also has unknown content.
and eax, 0x0000ffff ; clear upper bits of eax
; EAX = 0000EFGH
shl edx, 16 ; shift DX into position (will just shift the upper 16 junk bits away)
; EDX = ABCD000
or eax, edx ; combine in eax
; EAX = ABCDEFGH
之所以这样,工作原理是,ax
指eax
16个最低显著位。详情请参阅this SO问题和接受的答案。此方法也适用于imul
,但通常在处理汇编代码中的带符号数字时必须小心。
一个完整的例子:
bits 32
extern printf
global main
section .text
main:
push ebx
mov ax, 0x1234
mov bx, 0x10
mul bx
and eax, 0x0000ffff ; clear upper bits of eax
shl edx, 16 ; shift DX into position
or eax, edx ; and combine
push eax
push format
call printf
add esp, 8
mov eax, 0
pop ebx
ret
section .data
format: db "result = %8.8X",10,0
编译:
nasm -f elf32 -g -o test.o test.asm
gcc -m32 -o test test.o
更新:
在32位机器上它通常更容易和优选处理32位值,如果在上下文中是合理的。例如:
movzx eax, word [input1] ; Load 16-bit value and zero-extend into eax
movzx edx, word [input2] ; Use movsx if you want to work on signed values
mul eax, edx ; eax *= edx
这也说明了较新的,更易于使用,mul
一条指令的用法。您也可以像现在这样做,然后mov ax, [input1]
,然后再用movzx eax, ax
扩大尺寸。
我想知道是否可以先将DX:AX的内容放入内存中,然后执行mov eax,[mem32]' – Chris
当然:'mov [myInt],ax; mov [myInt + 2],dx; mov eax,[myInt]' – user786653