2

私はidiv適切に作業しようとしています.25などの割りたいebxものを入れてから、5などの割りたいものを入れてください。

idiv ebx

EAX次に、 = 5 とEDX= 0を置きます。

ただし、私のプログラムではそれを行いません。入力は100000000です

出力:

キロバイト: 100000000

メガバイト: 1869375819

ここで何が間違っているのか疑問に思っていましたか?

%include "asm_io.inc"
;
; initialized data is put in the .data segment
;
segment .data
prompt db "Please enter the number of bytes:", 0
param db "1 = Calculate it in kilobytes", 0Ah, "2 = Calculate it in megabytes", 10, 0
output db "Kilobytes: %d", 0Ah, "MegaBytes: %d", 10, 0
;
;
segment .bss
;
input resd 1
input2 resd 1
choice resd 1
;
; code is put in the .text segment
;
segment .text
    global  asm_main
extern printf
asm_main:
    enter   0,0              
    pusha

    mov eax, prompt
    call print_string
    call read_int
    mov [input], eax
    mov [input2], eax

    sub esp, 10h
    push dword [output]
    push dword [input2]
    push dword [input]


    mov eax, param
    call print_string
    call read_int

    cmp eax, 1
    je kilobyte; Jump if eax is equal to 1

    cmp eax, 2
    je megabyte; Jump if eax equal to 2

kilobyte:
    pop eax             ; Pop input into eax
    cdq             
    mov ebx, 1024       ; Put 1024 into ebx
    idiv ebx             ; EAX = 100000000/1024 = 97656
    mov [input], eax    ; Move 97656 into var=input
    push dword [input]  ; Put into stack
    jmp megabyte

megabyte:
    pop eax             ; Pop input into eax
    cdq         
    mov ebx, 1048576    ; Put 1048576 into ebx
    idiv ebx             ; EAX = 100000000/1024 = 95
    mov [input2], eax   ; Move 95 into var=input    
    push dword [input]  ; Put into stack
    jmp printOut

printOut:
    mov dword [esp], output
    call printf

    add esp, 4 * 3


    add esp, 10h

    popa
    mov     eax, 0            
    leave                     
    ret

アップデート

入れましxor edx, edxたが、以前と同じ出力が得られます。私は自分の電子ブックや他のサイトを調べましたが、同じことが書かれているので、何が間違っているのか本当にわかりません. idiv運がないルートも試してみました。

4

3 に答える 3

5

EDX を初期化する必要があります。それをゼロにして ( xor edx, edx)、署名なしの操作を使用するか、EAX をそれに署名拡張します ( cdq) 。


IDIV は次のように行います (リンク):

AX、DX:AX、または EDX:EAX レジスタの値 (被除数) をソース オペランド (除数) で除算 (符号付き) し、結果を AX (AH:AL)、DX:AX、または EDX:EAX に格納します。登録します。ソース オペランドは、汎用レジスタまたはメモリ位置にすることができます。

この命令のアクションは、次の表に示すように、オペランドのサイズ (被除数/除数) によって異なります。 IDIV 結果 [ヘッダー]オペランド

ここに画像の説明を入力

EBX で除算しているため、EDX:EAX から被除数を取得します。EDX をゼロに初期化しなかったため、ジャンク結果が得られました。

于 2013-11-08T06:53:11.780 に答える