assembly - 将两个数字放入 EAX 寄存器

标签 assembly nasm cpu-registers

我正在尝试将两个 16 位数字与以下 NASM 代码相乘:

mov ax, [input1]
mov bx, [input2]
mul bx

前面代码的结果存储在DX:AX

我尝试使用单独库“print_int”中的函数将整数打印到屏幕上。但 print_int 要求整数必须在 EAX 寄存器中。

如何将 32 位整数放入 EAX 寄存器中?

更新

我想出了这个

mov cx, dx  ;move upper half(16 bits) of result in cx
shl ecx, 16 ;shift the contents of ecx 16 bits to the left
mov cx, ax  ;move lower half(16 bits) of result in cx

最佳答案

像这样:

; 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所以问题和接受的答案。此方法也适用于 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 扩展大小。

关于assembly - 将两个数字放入 EAX 寄存器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7077585/

相关文章:

c++ - 是否可以在 C++ 中的单个操作中同时获得除法的模数和商数?

linux - 跳转后寄存器和变量不保存状态

c++ - 获取在寄存器中传递的参数的地址

cpu-registers - 6502使用有符号或无符号8位寄存器(JAVA)吗?

c++ - cout 能以某种方式改变变量吗?

macos - 通过替换为 NOP 来修补 CALLL 在用户空间中有效,但在内核空间中无效

assembly - 预取指令

c++ - 错误 : invalid instruction suffix for `push'

Linux x86 Bootstrap

linux - 在 x86 汇编语言中获取文件大小的简单方法