使用浮点数的printf:RAX值与浮点参数数量不符?示例代码是否有误?
x86-64汇编printf调用的RAX寄存器值错误分析
你完全正确,这段代码里的除法部分存在明显错误:调用printf前mov rax,1的设置是错的,应该改成mov rax,3,和乘法部分保持一致。
原因是x86-64的System V调用约定明确要求:调用printf这类可变参数函数时,RAX寄存器必须被设置为通过XMM寄存器传递的浮点参数的总数。
看除法对应的格式字符串f_div:"The float division of %f by %f is %f",10,0,里面有3个%f占位符,对应3个双精度浮点参数——分别是存在xmm0的number1、xmm1的number2、xmm2的除法结果。这时候必须把RAX设为3,告诉printf要从XMM寄存器里读取3个浮点参数。如果设成1,printf只会读取1个XMM参数,剩下的参数解析会混乱,大概率输出错误结果甚至导致程序崩溃。
原代码如下:
f_mul db "The float product of %f and %f is %f",10,0 f_div db "The float division of %f by %f is %f",10,0 ; multiplication movsd xmm2, [number1] ; double precision float into xmm mulsd xmm2, [number2] ; multiply with xmm ; print the result mov rdi,f_mul movsd xmm0, [number1] movsd xmm1, [number2] mov rax,3 ; three floats call printf ; division movsd xmm2, [number1] ; double precision float into xmm divsd xmm2, [number2] ; divide xmm0 ; print the result mov rdi,f_div movsd xmm0, [number1] movsd xmm1, [number2] mov rax,1 ; one float call printf
内容的提问来源于stack exchange,提问作者Tim
相关产品推荐
相关产品推荐

