Итак, я работаю над этим фрагментом кода сборки и столкнулся со странной проблемой: регистр XMM1
, похоже, теряет свое значение в середине выполнения, хотя я не думаю, что здесь используются какие-либо инструкции это может изменить его ценность. Ниже приведен проблемный c фрагмент кода.
MOVSD QWORD [RSP], XMM1 ;Copy to stack
MOV RDI, QWORD [RSP]
CALL printfcallfloat;Prints floating point value from the RDI register, preserves all registers
;Load 10 to the fpu stack
PUSH 10
FILD QWORD [RSP]
POP RDI
MOVSD QWORD [RSP], XMM0 ;Copy to stack
FLD QWORD [RSP];Load number float from XMM0 to the x87
;Do the math y = xmm0 (2), x=10 X*LOG2(Y)
FYL2X
;We now have the result of x*log2(y) in ST(0)
FSTP QWORD [RSP];Pop the result from the logarithm to the stack
MOVSD XMM0, QWORD [RSP];Move the result back to xmm0
;print XMM0 and XMM1
MOVSD QWORD [RSP], XMM0 ;Copy to stack
MOV RDI, QWORD [RSP]
CALL printfcallfloat;This preserves all registers
MOVSD QWORD [RSP], XMM1 ;Copy to stack
MOV RDI, QWORD [RSP]
CALL printfcallfloat;This preserves all registers
Это дает следующий вывод:
10.000000
10.000000
-nan
Я очень смущен тем, что здесь происходит.
РЕДАКТИРОВАТЬ: реализация функции печати выглядит следующим образом:
printfcallfloat:
;Value is passed here in RDI
PUSH RDI ;Preserve value of rdi
PUSH RAX ;Preserve value of RAX
pushxmm XMM0 ;Preserve XMM0
;Double is passed to printf in XMM0
;Now we move the value from the reg to the XMM0 using stack
PUSH RDI
popxmm XMM0
MOV AL, 1;We are passing one argument so al should be 1
MOV RDI, formatStrf ;Format string is passed in RDI
CALL printf
;Restore XMM0
popxmm XMM0
POP RAX
POP RDI
RET