我在装配时遇到以下行为的麻烦。 我正在组装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
我真的尝试过很多但没有成功。 非常感谢! :)
答案 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