Ввод двух чисел в регистр EAX - PullRequest
2 голосов
/ 16 августа 2011

Я пытаюсь умножить два 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

Ответы [ 2 ]

2 голосов
/ 16 августа 2011

Как это:

; 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 относится к 16 младшим значащим битам eax. Подробнее см. этот ТАК вопрос и принятый ответ. Этот метод также будет работать для 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.

1 голос
/ 16 августа 2011

Самый короткий путь ...

asm
//load test values in eax and exb
        mov     eax,    $00000102
        mov     ebx,    $00000304
//merge ex and bx to eax
        shl     ebx, 16
        shld    eax, ebx, 16
end;

результат в eax = $ 01020304

Если ты хочешь опозить тогда ...

asm
//load test values in eax and exb
        mov     eax,    $00000102
        mov     ebx,    $00000304
//merge ex and bx to eax
        shl     eax, 16
        shrd    eax, ebx, 16
end;

результат в eax = $ 03040102

...