[Cheat Engine] Was macht cvttss2si?
Ich habe dieses Wort noch nie gehört. Das ist mir vorhin aber bei einem OPCode aufgetaucht. Wofür steht cvttss2si? Und was macht das genau?
1 Antwort
CVTTSS2SI (Convert with truncation scalar single precision floating-point value to integer) ist eine x86 Prozessoranweisung, welche eine Gleitkommazahl (IEEE 754 binary32) in eine Ganzzahl (mit Vorzeichen, 32 oder 64bit je nach Zielregisterweite) umwandelt und dabei gegen null rundet:
https://www.felixcloutier.com/x86/cvttss2si
Das hat den Hintergrund, dass solche Zahlen in einer modernen CPU komplett anders verarbeitet werden: https://de.wikipedia.org/wiki/X87. Und somit gelegentlich hin und her umwandelt werden müssen.
![- (Cheat Engine, Assembler, opcode)](https://images.gutefrage.net/media/fragen-antworten/bilder/547339221/0_big.png?v=1717009004000)
Ja. Es ist "truncation" spezifiziert, das Ende wird also "Abgehackt": https://de.wikipedia.org/wiki/Trunkierung_(Mathematik). Das hat den Effekt, gegen null zu runden (auch wenn "normale" Rundung ein anderes Ergebnis geben würde):
8.92 -> 8
-2.57 -> -2
Ein praktisches Beispiel:
; cvttss2si demo
; ------------------------------------------------------
; Author: JanaL161
; Date: 2024-05-30
; ------------------------------------------------------
; compilation instructions (x86_64-pc-linux-gnu)
;
; nasm -f elf64 -g -F dwarf -o cvttss2si.o cvttss2si.asm
; gcc -nostartfiles -no-pie -o cvttss2si cvttss2si.o -lc
; ------------------------------------------------------
section .data
float_a dd 8.92
float_b dd -2.57
int_a dd 0
int_b dd 0
format_str db "val: %d", 10, 0
section .text
extern printf
global _start
_start:
; load float_a into xmm0 and float_b into xmm1
mov eax, [float_a]
movd xmm0, eax
mov eax, [float_b]
movd xmm1, eax
; run cvttss2si and store the result into int_a and int_b respectively
cvttss2si eax, xmm0
mov [int_a], eax
cvttss2si eax, xmm1
mov [int_b], eax
; print int_a and int_b
mov rdi, format_str
mov rsi, [int_a]
call printf
mov rdi, format_str
mov rsi, [int_b]
call printf
; exit with 0
mov rax, 60
xor rdi,rdi
syscall
Ausgabe:
val: 8
val: -2
Die Rundung ist immer runter, richtig? Also von zb. 2,9 auf 2?