装配印刷浮子

时间:2012-11-25 19:04:30

标签: c++ c assembly x86

我在装配时遇到以下行为的麻烦。 我正在组装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个数字,没有四舍五入) e.g。

Divide : 3 / 4 = 0.75

表示19和1000:

Divide : 19 / 1000 = 0.01

和8和2:

Divide : 8 / 2 = 4.00

我真的尝试过很多但没有成功。 非常感谢! :)

1 个答案:

答案 0 :(得分: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

请参阅code in operation