0

アセンブリで次のアクションに問題があります。アセンブリIA32に取り組んでいます。-4(%ebp)= xおよび-8(%ebp)= yと仮定すると、すでにユーザーから取得しています。これはコードです:

format1:    .string "Multiply : %u * %u = %llu\n"
format2:    .string "Divide : %u / %u = %u\n"

# operation multiply
movl    -4(%ebp),   %eax
mull    -8(%ebp)
pushl   %edx
pushl   %eax
pushl   -8(%ebp)
pushl   -4(%ebp)
pushl   $format1
call    printf

# operation divide
movl    -4(%ebp),    %eax   
divl    -8(%ebp)
pushl    %eax
pushl   -8(%ebp)
pushl   -4(%ebp)
pushl   $format2
    call    printf

乗算の結果が%lluにある理由は、2つの長い数値を乗算して、64バイトに達しても結果を出力できるようにするためです。また、%edxでは、mullコマンドが64バイトの結果の「他の32バイト」を保存するため、printf用にスタックにプッシュする必要があります。たとえば、この出力が必要です。

 Multiply : 4000000000 * 2 = 16000000000

また、3と4の除算演算でX.YZの結果を返すようにします。(仮数で2つ以下の数値、および四捨五入なし)eg

Divide : 3 / 4 = 0.75

19および1000の場合:

Divide : 19 / 1000 = 0.01

そして8と2のために:

Divide : 8 / 2 = 4.00

私は本当に結果を得るためにたくさん試みましたが、成功しませんでした。どうもありがとう!:)

4

1 に答える 1

1

はい、もちろん使用できますscanf。正しい引数を渡すだけです。言われたように、浮動小数点の結果を得るには、いくつかの浮動小数点除算と浮動小数点形式を使用して印刷する必要があります。

呼び出し規約に従って、ebxレジスタの値を保持する必要があることに注意してください。さらに、スタックのバランスを保ち、できれば整列させる必要があります。

考えられる解決策:

.comm x,4,4
.comm y,4,4

.section    .rodata

format1:    .string "Div : %d / %d = %g\n"
format2:    .string "Mod : %d %% %d = %d\n"
format3:    .string "%d %d"

.text
.globl  main
.type   main, @function
main:
    subl $32, %esp # allocate space, preserve alignment

    movl $format3, (%esp)
    movl $x, 4(%esp)
    movl $y, 8(%esp)
    call scanf

# operation divide
    fildl x
    fidivl y
    fstpl 12(%esp) # x / y

    movl $format1, (%esp)
    movl x, %eax
    movl %eax, 4(%esp)
    movl y, %eax
    movl %eax, 8(%esp)
    call printf

# operation modulo
    movl x, %eax
    cltd
    idivl y
    movl $format2, (%esp)
    movl x, %eax
    movl %eax, 4(%esp)
    movl y, %eax
    movl %eax, 8(%esp)
    movl %edx, 12(%esp)
    call printf

    addl $32, %esp
    xor %eax, %eax
    ret

動作中のコードを参照してください。

于 2012-11-25T20:02:20.030 に答える