[Cheat Engine] Was macht cvttss2si?

1 Antwort

Vom Beitragsersteller als hilfreich ausgezeichnet

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.

Bild zum Beitrag

 - (Cheat Engine, Assembler, opcode)

MissyCooper 
Beitragsersteller
 29.05.2024, 23:38

Die Rundung ist immer runter, richtig? Also von zb. 2,9 auf 2?

0
JanaL161  30.05.2024, 01:19
@MissyCooper

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
1