So prüfen Sie, ob eine Binärdatei unter Linux SSE4 oder AVX erfordert

12126
user2284570

/proc/cpuinfoErlaubt es unter Linux, auf einfache Weise alle CPU-Flags der Maschine zu überprüfen.
Wenn für ein Programm eine Obermenge des Befehlssatzes einer Maschine erforderlich ist, können Sie dies am einfachsten ermitteln, indem Sie es ausführen und sehen, ob ein SIGILLSignal ausgegeben wird.

In meinem Fall unterstützen jedoch alle meine Prozessoren mindestens SSE4.1 und AVX.
Gibt es eine einfache Möglichkeit, zu überprüfen, ob eine Binärdatei spezielle Anweisungen enthält?

15
Möglicherweise gibt es Emulatoren, mit denen Sie auswählen können, welche Befehlssätze aktiviert sind. QEMU unterstützt AVX derzeit nicht, so dass dort möglicherweise "nicht funktioniert" wie erwartet: http://superuser.com/questions/453786/how-do-i-get-avx-support-in-qemu || http://superuser.com/questions/548740/disabling-instruction-set-in-virtualbox Ciro Santilli 新疆改造中心 六四事件 法轮功 vor 8 Jahren 0
"objdump --disassemble" führt eine Demontage durch. Sie können "objdump" verwenden, um eine Liste von Mnemonics zu erstellen. Es ist Teil von Binutils, daher auf GNU Linux-Systemen verfügbar. Die zusätzlichen Anweisungen können auch vorhanden sein, aber * dürfen nicht ausgeführt werden. Das Programm könnte Laufzeitschutz haben. jww vor 6 Jahren 2
@jww: heemm, ja, aber ich habe mir die Mühe gemacht, überall eine ausführbare Datei laufen zu lassen, nicht über 600 Opcodes zu lernen, um in Assembler zu programmieren. user2284570 vor 6 Jahren 0
Nun, man muss lernen, was man verwenden kann (und nicht kann). Das ist deine Verantwortung. Ich nehme an, Sie könnten mit `-mavx` kompilieren, um sicherzustellen, dass der Compiler nur die AVX-ISA auswählt, aber es gibt Möglichkeiten, es zu umgehen. Beispielsweise kann der Inline-Assembler normalerweise die ISA-Prüfungen des Compilers umgehen. jww vor 6 Jahren 0
@jww: und wenn die Binärdatei eine geschlossene Quelle ist * (der Quellcode wird nach dem Erstellen gelöscht) * Shared Object, das von einem proprietären Skript / Compiler erstellt wird? user2284570 vor 6 Jahren 0
Alle nachstehenden Antworten greifen durch die Demontage hindurch. Denken Sie daran, dass der Code selbst über Wachen verfügen kann (wie von @jww erwähnt), dh er erkennt den Befehlssatz, der von der CPU unterstützt wird, und verwendet die schnellste Routine, die auf der CPU ausgeführt werden kann, der objdump enthält jedoch weiterhin die SSE4 / AVX-Anweisungen. Kurz gesagt: Das Vorhandensein dieser Opcodes bedeutet nicht zwangsläufig, dass sie verwendet werden. OTOH, wenn keine vorhanden sind, können Sie sicher sein, dass die SSE4 / AVX-Kompatibilität kein Problem darstellt. Ro-ee vor 6 Jahren 0
@ Ro-ee: in meinem Fall nur Befehlszeilen-Compiler-Argumente. Wenn sie also anwesend sind, werden sie vom Prozessor abgerufen. user2284570 vor 6 Jahren 0
[Welche Anweisungen werden von x86-64-Binärdateien verwendet?] (https://unix.stackexchange.com/q/249380/44425), [So überprüfen Sie, ob der kompilierte Code Sse- und Avx-Anweisungen verwendet?] (https: // stackoverflow.). com / q / 47878352/995714) phuclv vor 5 Jahren 0

4 Antworten auf die Frage

16
Kyselejsyreček

Ich stieß auf das gleiche Problem, als ich versuchte, die GCC-Optimierungsprozesse zu verstehen und herauszufinden, welche Anweisungen während dieses Prozesses verwendet wurden oder nicht. Da ich nicht mit der enormen Anzahl von Operationscodes vertraut bin, suchte ich nach einer Möglichkeit, bestimmte Anweisungen (beispielsweise SSE3) innerhalb des disassemblierten Codes zu visualisieren oder zumindest einige minimale Statistiken zu drucken, z. B. ob und wie viele dieser Anweisungen vorhanden sind im binären.

Ich habe keine Lösung gefunden, aber die Antwort von Jonathan Ben-Avraham erwies sich als sehr nützlich, da auf eine große (und teilweise sogar strukturierte) Quelle für Operationscodes hingewiesen wird. Basierend auf diesen Daten habe ich ein Bash-Skript geschrieben, das bestimmte Befehlssätze visualisieren oder Statistiken über sie drucken kann, grepwenn sie mit der Ausgabe von eingespeist werden objdump.

Die Liste der Operationscodes wurde in ein eigenständiges Bash-Skript umgewandelt, das dann (zur besseren Lesbarkeit) in die Hauptdatei aufgenommen wird, die ich einfach benannt habe opcode. Da Opcodes gas.vim( Shirk- vimSyntaxdefinitionen, von Jonathans Antwort) systematisch (scheinbar) nach verschiedenen CPU-Architekturen gruppiert wurden, habe ich versucht, diese Unterteilung beizubehalten und eine Architektur-> Befehlssatzzuordnung vorzunehmen . Ich bin mir jetzt nicht sicher, ob das eine gute Idee war. Das Mapping ist nicht genau und ich musste sogar einige Änderungen am Original vornehmengas.vimGruppierung. Da architekturbezogene Befehlssätze nicht meine ursprüngliche Absicht waren, habe ich nur versucht, Befehlssätze von im Internet beschriebenen Hauptarchitekturen zu erstellen, jedoch ohne die Dokumentation der Hersteller zu konsultieren. AMD-Architekturen erscheinen mir überhaupt nicht zuverlässig (ausgenommen Befehlssätze wie 3DNow! Und SSE5). Ich entschied mich jedoch, den Code für Anweisungssätze verschiedener Architekturen hier zu belassen, damit jemand anderes sie prüfen und korrigieren / verbessern und anderen vorläufigen Ergebnissen mitteilen kann.

Beginn der Hauptdatei mit dem Namen opcode:

#!/bin/bash # # Searches disassembled code for specific instructions. # # Opcodes obtained from: https://github.com/Shirk/vim-gas/blob/master/syntax/gas.vim # # List of opcodes has been obtained using the following commands and making a few modifications: # echo '#!/bin/bash' > Opcode_list # wget -q -O- https://raw.githubusercontent.com/Shirk/vim-gas/master/syntax/gas.vim \ # | grep -B1 -E 'syn keyword gasOpcode_|syn match gasOpcode' | \ # sed -e '/^--$/d' -e 's/"-- Section:/\n#/g' \ # -e 's/syn keyword gasOpcode_\([^\t]*\)*\(\t\)*\(.*\)/Opcode_\1="\$ \3"/g' \ # -e 's/Opcode_PENT_3DNOW/Opcode_ATHLON_3DNOW/g' -e 's/\\//g' \ # -e 's/syn match gasOpcode_\([^\t]*\)*.*\/<\(.*\)>\//Opcode_\1="\$ \2"/g' \ # >> Opcode_list # # Modify file Opcode_list replacing all occurrences of: # * Opcode_Base within the section "Tejas New Instructions (SSSE3)" with Opcode_SSSE3 # * Opcode_Base within the section "Willamette MMX instructions (SSE2 SIMD Integer Instructions)" # with Opcode_WILLAMETTE_Base  # return values EXIT_FOUND=0 EXIT_NOT_FOUND=1 EXIT_USAGE=2  # settings InstSet_Base="" Recursive=false Count_Matching=false Leading_Separator='\s' Trailing_Separator='(\s|$)' # $ matches end of line for non-parametric instructions like nop Case_Insensitive=false Invert=false Verbose=false Stop_After=0 Line_Numbers=false Leading_Context=0 Trailing_Context=0  source Opcode_list # include opcodes from a separate file  # GAS-specific opcodes (unofficial names) belonging to the x64 instruction set. # They are generated by GNU tools (e.g. GDB, objdump) and specify a variant of ordinal opcodes like NOP and MOV. # If you do not want these opcodes to be recognized by this script, comment out the following line. Opcode_X64_GAS="nopw nopl movabs"   # instruction sets InstSet_X86="8086_Base 186_Base 286_Base 386_Base 486_Base PENT_Base P6_Base KATMAI_Base WILLAMETTE_Base PENTM_Base" InstSet_IA64="IA64_Base" InstSet_X64="PRESCOTT_Base X64_Base X86_64_Base NEHALEM_Base X64_GAS" InstSet_MMX="PENT_MMX KATMAI_MMX X64_MMX" InstSet_MMX2="KATMAI_MMX2" InstSet_3DNOW="ATHLON_3DNOW" InstSet_SSE="KATMAI_SSE P6_SSE X64_SSE" InstSet_SSE2="SSE2 X64_SSE2" InstSet_SSE3="PRESCOTT_SSE3" InstSet_SSSE3="SSSE3" InstSet_VMX="VMX X64_VMX" InstSet_SSE4_1="SSE41 X64_SSE41" InstSet_SSE4_2="SSE42 X64_SSE42" InstSet_SSE4A="AMD_SSE4A" InstSet_SSE5="AMD_SSE5" InstSet_FMA="FUTURE_FMA" InstSet_AVX="SANDYBRIDGE_AVX"  InstSetDep_X64="X86" InstSetDep_MMX2="MMX" InstSetDep_SSE2="SSE" InstSetDep_SSE3="SSE2" InstSetDep_SSSE3="SSE3" InstSetDep_SSE4_1="SSSE3" InstSetDep_SSE4_2="SSE4_1" InstSetDep_SSE4A="SSE3" InstSetDep_SSE5="FMA AVX" # FIXME not reliable  InstSetList="X86 IA64 X64 MMX MMX2 3DNOW SSE SSE2 SSE3 SSSE3 VMX SSE4_1 SSE4_2 SSE4A SSE5 FMA AVX"   # architectures Arch_8086="8086_Base" Arch_186="186_Base" Arch_286="286_Base" Arch_386="386_Base" Arch_486="486_Base" Arch_Pentium="PENT_Base PENT_MMX" # Pentium = P5 architecture Arch_Athlon="ATHLON_3DNOW" Arch_Deschutes="P6_Base P6_SSE" # Pentium II Arch_Katmai="KATMAI_Base KATMAI_MMX KATMAI_MMX2 KATMAI_SSE" # Pentium III Arch_Willamette="WILLAMETTE_Base SSE2" # original Pentium IV (x86) Arch_PentiumM="PENTM_Base" Arch_Prescott="PRESCOTT_Base X64_Base X86_64_Base X64_SSE2 PRESCOTT_SSE3 VMX X64_VMX X64_GAS" # later Pentium IV (x64) with SSE3 (Willamette only implemented SSE2 instructions) and VT (VT-x, aka VMX) Arch_P6="" Arch_Barcelona="ATHLON_3DNOW AMD_SSE4A" Arch_IA64="IA64_Base" # 64-bit Itanium RISC processor; incompatible with x64 architecture Arch_Penryn="SSSE3 SSE41 X64_SSE41" # later (45nm) Core 2 with SSE4.1 Arch_Nehalem="NEHALEM_Base SSE42 X64_SSE42" # Core i# Arch_SandyBridge="SANDYBRIDGE_AVX" Arch_Haswell="FUTURE_FMA" Arch_Bulldozer="AMD_SSE5"  ArchDep_8086="" ArchDep_186="8086" ArchDep_286="186" ArchDep_386="286" ArchDep_486="386" ArchDep_Pentium="486" ArchDep_Athlon="Pentium" # FIXME not reliable ArchDep_Deschutes="Pentium" ArchDep_Katmai="Deschutes" ArchDep_Willamette="Katmai" ArchDep_PentiumM="Willamette" # FIXME Pentium M is a Pentium III modification (with SSE2). Does it support also WILLAMETTE_Base instructions? ArchDep_Prescott="Willamette" ArchDep_P6="Prescott" # P6 started with Pentium Pro; FIXME Pentium Pro did not support MMX instructions (introduced again in Pentium II aka Deschutes) ArchDep_Barcelona="Prescott" # FIXME not reliable ArchDep_IA64="" ArchDep_Penryn="P6" ArchDep_Nehalem="Penryn" ArchDep_SandyBridge="Nehalem" ArchDep_Haswell="SandyBridge" ArchDep_Bulldozer="Haswell" # FIXME not reliable  ArchList="8086 186 286 386 486 Pentium Athlon Deschutes Katmai Willamette PentiumM Prescott P6 Barcelona IA64 Penryn Nehalem SandyBridge Haswell Bulldozer" 

Ein Beispiel für eine Opcode_listDatei, die mit den Anweisungen opcodevom 27. Oktober 2014 erstellt und geändert wurde, finden Sie unter http://pastebin.com/yx4rCxqs . Sie können diese Datei direkt in opcodedie source Opcode_listZeile einfügen . Ich habe diesen Code herausgegeben, weil Stack Exchange mich keine so große Antwort senden lässt.

Zum Schluss noch der Rest der opcodeDatei mit der eigentlichen Logik:

usage() { echo "Usage: $0 OPTIONS" echo "" echo " -r set instruction sets recursively according to dependency tree (must precede -a or -s)" echo " -a set architecture" echo " -s set instruction set" echo " -L show list of available architectures" echo " -l show list of available instruction sets" echo " -i show base instruction sets of current instruction set (requires -a and/or -s)" echo " -I show instructions in current instruction set (requires -a and/or -s)" echo " -c print number of matching instructions instead of normal output" echo " -f find instruction set of the following instruction (regex allowed)" echo " -d set leading opcode separator (default '$Leading_Separator')" echo " -D set trailing opcode separator (default '$Trailing_Separator')" echo " -C case-insensitive" echo " -v invert the sense of matching" echo " -V print all lines, not just the highlighted" echo " -m stop searching after n matched instructions" echo " -n print line numbers within the original input" echo " -B print n instructions of leading context" echo " -A print n instructions of trailing context" echo " -h print this help" echo echo "Multiple architectures and instruction sets can be used." echo echo "Typical usage is:" echo " objdump -M intel -d FILE | $0 OPTIONS" echo " objdump -M intel -d FILE | $0 -s SSE2 -s SSE3 -V Highlight SSE2 and SSE3 within FILE." echo " objdump -M intel -d FILE | tail -n +8 | $0 -r -a Haswell -v -m 1 Find first unknown instruction." echo " $0 -C -f ADDSD Find which instruction set an opcode belongs to." echo " $0 -f .*fma.* Find all matching instructions and their instruction sets." echo echo "The script uses Intel opcode syntax. When used in conjunction with objdump, \`-M intel' must be set in order to prevent opcode translation using AT&T syntax." echo echo "BE AWARE THAT THE LIST OF KNOWN INSTRUCTIONS OR INSTRUCTIONS SUPPORTED BY PARTICULAR ARCHITECTURES (ESPECIALLY AMD'S) IS ONLY TENTATIVE AND MAY CONTAIN MISTAKES!" kill -TRAP $TOP_PID }  list_contains() { # Returns 0 if $2 is in array $1, 1 otherwise. local e for e in $1; do [ "$e" = "$2" ] && return 0 done return 1 }  build_instruction_set() { # $1 = enum { Arch, InstSet }, $2 = architecture or instruction set as obtained using -L or -l, $3 = "architecture"/"instruction set" to be used in error message local e list_contains "`eval echo \\\$$List`" "$2" || (echo "$2 is not a valid $3."; usage) # Test if the architecture/instruction set is valid. if [ -n "`eval echo \\\$$_$`" ]; then # Add the instruction set(s) if any. for e in `eval echo \\\$$_$`; do # Skip duplicates. list_contains "$InstSet_Base" $e || InstSet_Base="$e $InstSet_Base" done fi if [ $Recursive = true ]; then for a in `eval echo \\\$$Dep_$2`; do build_instruction_set $1 $a "$3" done fi InstSet_Base="`echo $InstSet_Base | sed 's/$ *//'`" # Remove trailing space. }  trap "exit $EXIT_USAGE" TRAP # Allow usage() function to abort script execution. export TOP_PID=$$ # PID of executing process.  # Parse command line arguments. while getopts ":ra:s:LliIcf:Fd:D:CvVm:nB:A:h" o; do case $o in r) Recursive=true ;; a) build_instruction_set Arch "$OPTARG" "architecture" ;; s) build_instruction_set InstSet "$OPTARG" "instruction set" ;; L) echo $ArchList; exit $EXIT_USAGE ;; l) echo $InstSetList; exit $EXIT_USAGE ;; i) if [ -n "$InstSet_Base" ]; then echo $InstSet_Base exit $EXIT_USAGE else echo -e "No instruction set or architecture set.\n" usage fi ;; I) if [ -n "$InstSet_Base" ]; then for s in $InstSet_Base; do echo -ne "\e[31;1m$s:\e[0m " eval echo "\$Opcode_$s" done exit $EXIT_USAGE else echo -e "No instruction set or architecture set.\n" usage fi ;; c) Count_Matching=true ;; f) # Unlike architectures, instruction sets are disjoint. Found=false for s in $InstSetList; do for b in `eval echo \\\$InstSet_$s`; do Found_In_Base=false for i in `eval echo \\\$Opcode_$b`; do if [[ "$i" =~ ^$OPTARG$ ]]; then $Found_In_Base || echo -ne "Instruction set \e[33;1m$s\e[0m (base instruction set \e[32;1m$b\e[0m):" echo -ne " \e[31;1m$i\e[0m" Found_In_Base=true Found=true fi done $Found_In_Base && echo "" done done if [ $Found = false ]; then echo -e "Operation code \e[31;1m$OPTARG\e[0m has not been found in the database of known instructions." \ "Perhaps it is translated using other than Intel syntax. If obtained from objdump, check if the \`-M intel' flag is set." \ "Be aware that the search is case sensitive by default (you may use the -C flag, otherwise only lower case opcodes are accepted)." exit $EXIT_NOT_FOUND else exit $EXIT_FOUND fi ;; d) Leading_Separator="$OPTARG" ;; D) Trailing_Separator="$OPTARG" ;; C) Case_Insensitive=true ;; v) Invert=true ;; V) Verbose=true ;; m) Stop_After=$OPTARG ;; n) Line_Numbers=true ;; B) Leading_Context=$OPTARG ;; A) Trailing_Context=$OPTARG ;; h) usage ;; \?) echo -e "Unknown option: -$OPTARG\n" usage ;; esac done shift $((OPTIND-1)) [ -n "$1" ] && echo -e "Unknown command line parameter: $1\n" && usage [ -z "$InstSet_Base" ] && usage  # Create list of grep parameters. Grep_Params="--color=auto -B $Leading_Context -A $Trailing_Context" [ $Count_Matching = true ] && Grep_Params="$Grep_Params -c" [ $Case_Insensitive = true ] && Grep_Params="$Grep_Params -i" [ $Invert = true ] && Grep_Params="$Grep_Params -v" [ $Stop_After -gt 0 ] && Grep_Params="$Grep_Params -m $Stop_After" [ $Line_Numbers = true ] && Grep_Params="$Grep_Params -n"  # Build regular expression for use in grep. RegEx="" for s in $InstSet_Base; do eval RegEx=\"$RegEx \$Opcode_$s\" done # Add leading and trailing opcode separators to prevent false positives. RegEx="$Leading_Separator`echo $RegEx | sed "s/ /$(echo "$Trailing_Separator"|sed 's/[\/&]/\\\&/g')|$(echo "$Leading_Separator"|sed 's/[\/&]/\\\&/g')/g"`$Trailing_Separator"  [ $Verbose = true -a $Count_Matching = false ] && RegEx="$RegEx|\$"  # The actual search. grep $Grep_Params -E "$RegEx" && exit $EXIT_FOUND || exit $EXIT_NOT_FOUND 

Bitte beachten Sie, dass bei einer zu großen Suchabfrage (z. B. mit Haswell-Befehlssatz und dem -rSchalter - dies umfasst Hunderte von Anweisungen) die Berechnung möglicherweise langsam vonstatten geht und große Eingaben dauern, für die dieses einfache Skript nicht vorgesehen war .

Detaillierte Informationen zur Verwendung finden Sie hier

./opcode -h 

Das gesamte opcodeSkript (einschließlich Opcode_list) finden Sie unter http://pastebin.com/A8bAuHAP .

Fühlen Sie sich frei, um das Tool zu verbessern und alle Fehler zu korrigieren, die ich gemacht habe. Zum Schluss möchte ich Jonathan Ben-Avraham für seine großartige Idee, Shirks gas.vimDatei zu verwenden, danken .

BEARBEITEN: Das Skript kann jetzt herausfinden, zu welchem ​​Befehlssatz ein Operationscode gehört (regulärer Ausdruck kann verwendet werden).

8
Peter

Ich habe ein Programm in Rust ausgespielt, das versucht, dies zu tun. Ich denke, es funktioniert, obwohl es undokumentiert und furchtbar fragil ist:

https://github.com/pkgw/elfx86exts

Verwendungsbeispiel:

$ cd elfx86exts $ cargo build [things happen] $ cargo run -- /bin/ls Compiling elfx86exts v0.1.0 (file:///home/peter/sw/elfx86exts) Finished dev [unoptimized + debuginfo] target(s) in 1.9 secs Running `target/debug/elfx86exts /bin/ls` MODE64 CMOV SSE2 SSE1 
Ich habe versucht, es auf libtensorflow.so (sha224: 8f665acf0f455d5056014dfa2d48c22ab6cf83eb073842e8304878d0) von [this] (https://www.archlinux.org/packages/community/x86_64/tensorflow-opt-cuda/) zu laufen ) und es hat meinen gesamten Computer eingefroren. Philippe vor 5 Jahren 0
@Philippe Bitte melde dich bei GitHub! Das ist der bessere Ort, um solche Themen zu diskutieren, denke ich. Peter vor 5 Jahren 0
Ok, ich habe ein Problem auf Ihrem Github erstellt. Philippe vor 5 Jahren 0
6
Jonathan Ben-Avraham

Leider scheint es bis heute kein bekanntes Dienstprogramm zu geben, das den erforderlichen Befehlssatz aus einer bestimmten ausführbaren Datei erkennt.

Das Beste, was ich für x86 vorschlagen kann, ist die Verwendung objdump -dder ELF-Binärdatei, um die ausführbaren Abschnitte in Gnu Assemply language ( gas) zu zerlegen . Verwenden Sie dann die vimSyntaxdefinitionen von Shirk, um entweder grepdurch die Assemblycodedatei zu navigieren oder den Assemblercode visuell nach einer gasOpcode_SSE41oder den gasOpcode_SANDYBRIDGE_AVXAnweisungen zu durchsuchen, die Sie in der gas.vimDatei von Shirk sehen .

Die Assemblersprachendatei enthält die Anweisungen auf Maschinenebene ("Opcodes"), die der Compiler beim Kompilieren des Programms generiert hat. Wenn das Programm mit Flags zur Kompilierungszeit für SSE- oder AVX-Anweisungen kompiliert wurde und der Compiler SSE- oder AVX-Anweisungen ausgegeben hat, sollten Sie einen oder mehrere SSE- oder AVX-Opcodes in der Disassembly-Liste von sehen objdump -d.

Wenn Sie beispielsweise grep vroundsdbdie Assemblycodedatei verwenden und eine Übereinstimmung finden, wissen Sie, dass für die Binärdatei AVX-Funktionen zur Ausführung erforderlich sind.

Es gibt eine Reihe von subarchitekturspezifischen Anweisungen für x86, wie Sie aus Shirks gas.vimDatei sehen können. grepPing für alle Opcodes für jede Subarchitektur wäre allerdings langwierig. Das Erstellen eines C-, Perl- oder Python-Programms zu diesem Zweck könnte eine ausgezeichnete Idee für ein Open Source-Projekt sein, insbesondere wenn Sie jemanden finden könnten, der es für ARM, PPC und andere Architekturen erweitert.

Was ist der Zweck von Gas: Ich konnte das Programm nicht finden? user2284570 vor 10 Jahren 0
@ user2284570: Ich habe die Antwort so bearbeitet, dass sie sich auf Ihren Kommentar bezieht. HTH. Jonathan Ben-Avraham vor 10 Jahren 0
Sse4.2 + AVX + 3DNOW repräsentieren Hunderte von Anweisungen. Es würde lange dauern, eine Suche für jeden von ihnen zu starten ... user2284570 vor 10 Jahren 0
@ user2284570: Ja, das habe ich erwähnt. Wenn Sie dies regelmäßig tun müssen, ist es besser, ein Perl-Skript zu schreiben, das auf Shirks `gas.vim` basiert. OTOH Wenn dies ein One-Shot-Problem ist, können Sie leicht die Muster der Opcodes lernen, die zwischen den Unterarchitekturen unterscheiden. Jonathan Ben-Avraham vor 10 Jahren 0
Ich denke, eine Bibliothek für den Umgang mit Opcodes wäre etwas Großartiges für den Einstieg ... user2284570 vor 10 Jahren 0
6
Ohne Kleidung

Zuerst dekompilieren Sie Ihre Binärdatei:

objdump -d binary > binary.asm 

Dann finden Sie alle SSE4-Anweisungen in der Assembly-Datei:

gawk '/\<(mpsadbw|phminposuw|pmulld|pmuldq|dpps|dppd|blendps|blendpd|blendvps|blendvpd|pblendvb|pblenddw|pminsb|pmaxsb|pminuw|pmaxuw|pminud|pmaxud|pminsd|pmaxsd|roundps|roundss|roundpd|roundsd|insertps|pinsrb|pinsrd|pinsrq|extractps|pextrb|pextrd|pextrw|pextrq|pmovsxbw|pmovzxbw|pmovsxbd|pmovzxbd|pmovsxbq|pmovzxbq|pmovsxwd|pmovzxwd|pmovsxwq|pmovzxwq|pmovsxdq|pmovzxdq|ptest|pcmpeqq|pcmpgtq|packusdw|pcmpestri|pcmpestrm|pcmpistri|pcmpistrm|crc32|popcnt|movntdqa|extrq|insertq|movntsd|movntss|lzcnt)\>/' binary.asm 

(Hinweis: CRC32 stimmt möglicherweise mit Kommentaren überein.)

Hier finden Sie die gängigsten AVX-Anweisungen (einschließlich der AVX2- und AVX-512-Familie und einiger FMAs wie vfmadd213pd):

gawk '/\<(vmovapd|vmulpd|vaddpd|vsubpd|vfmadd213pd|vfmadd231pd|vfmadd132pd|vmulsd|vaddsd|vmosd|vsubsd|vbroadcastss|vbroadcastsd|vblendpd|vshufpd|vroundpd|vroundsd|vxorpd|vfnmadd231pd|vfnmadd213pd|vfnmadd132pd|vandpd|vmaxpd|vmovmskpd|vcmppd|vpaddd|vbroadcastf128|vinsertf128|vextractf128|vfmsub231pd|vfmsub132pd|vfmsub213pd|vmaskmovps|vmaskmovpd|vpermilps|vpermilpd|vperm2f128|vzeroall|vzeroupper|vpbroadcastb|vpbroadcastw|vpbroadcastd|vpbroadcastq|vbroadcasti128|vinserti128|vextracti128|vpminud|vpmuludq|vgatherdpd|vgatherqpd|vgatherdps|vgatherqps|vpgatherdd|vpgatherdq|vpgatherqd|vpgatherqq|vpmaskmovd|vpmaskmovq|vpermps|vpermd|vpermpd|vpermq|vperm2i128|vpblendd|vpsllvd|vpsllvq|vpsrlvd|vpsrlvq|vpsravd|vblendmpd|vblendmps|vpblendmd|vpblendmq|vpblendmb|vpblendmw|vpcmpd|vpcmpud|vpcmpq|vpcmpuq|vpcmpb|vpcmpub|vpcmpw|vpcmpuw|vptestmd|vptestmq|vptestnmd|vptestnmq|vptestmb|vptestmw|vptestnmb|vptestnmw|vcompresspd|vcompressps|vpcompressd|vpcompressq|vexpandpd|vexpandps|vpexpandd|vpexpandq|vpermb|vpermw|vpermt2b|vpermt2w|vpermi2pd|vpermi2ps|vpermi2d|vpermi2q|vpermi2b|vpermi2w|vpermt2ps|vpermt2pd|vpermt2d|vpermt2q|vshuff32x4|vshuff64x2|vshuffi32x4|vshuffi64x2|vpmultishiftqb|vpternlogd|vpternlogq|vpmovqd|vpmovsqd|vpmovusqd|vpmovqw|vpmovsqw|vpmovusqw|vpmovqb|vpmovsqb|vpmovusqb|vpmovdw|vpmovsdw|vpmovusdw|vpmovdb|vpmovsdb|vpmovusdb|vpmovwb|vpmovswb|vpmovuswb|vcvtps2udq|vcvtpd2udq|vcvttps2udq|vcvttpd2udq|vcvtss2usi|vcvtsd2usi|vcvttss2usi|vcvttsd2usi|vcvtps2qq|vcvtpd2qq|vcvtps2uqq|vcvtpd2uqq|vcvttps2qq|vcvttpd2qq|vcvttps2uqq|vcvttpd2uqq|vcvtudq2ps|vcvtudq2pd|vcvtusi2ps|vcvtusi2pd|vcvtusi2sd|vcvtusi2ss|vcvtuqq2ps|vcvtuqq2pd|vcvtqq2pd|vcvtqq2ps|vgetexppd|vgetexpps|vgetexpsd|vgetexpss|vgetmantpd|vgetmantps|vgetmantsd|vgetmantss|vfixupimmpd|vfixupimmps|vfixupimmsd|vfixupimmss|vrcp14pd|vrcp14ps|vrcp14sd|vrcp14ss|vrndscaleps|vrndscalepd|vrndscaless|vrndscalesd|vrsqrt14pd|vrsqrt14ps|vrsqrt14sd|vrsqrt14ss|vscalefps|vscalefpd|vscalefss|vscalefsd|valignd|valignq|vdbpsadbw|vpabsq|vpmaxsq|vpmaxuq|vpminsq|vpminuq|vprold|vprolvd|vprolq|vprolvq|vprord|vprorvd|vprorq|vprorvq|vpscatterdd|vpscatterdq|vpscatterqd|vpscatterqq|vscatterdps|vscatterdpd|vscatterqps|vscatterqpd|vpconflictd|vpconflictq|vplzcntd|vplzcntq|vpbroadcastmb2q|vpbroadcastmw2d|vexp2pd|vexp2ps|vrcp28pd|vrcp28ps|vrcp28sd|vrcp28ss|vrsqrt28pd|vrsqrt28ps|vrsqrt28sd|vrsqrt28ss|vgatherpf0dps|vgatherpf0qps|vgatherpf0dpd|vgatherpf0qpd|vgatherpf1dps|vgatherpf1qps|vgatherpf1dpd|vgatherpf1qpd|vscatterpf0dps|vscatterpf0qps|vscatterpf0dpd|vscatterpf0qpd|vscatterpf1dps|vscatterpf1qps|vscatterpf1dpd|vscatterpf1qpd|vfpclassps|vfpclasspd|vfpclassss|vfpclasssd|vrangeps|vrangepd|vrangess|vrangesd|vreduceps|vreducepd|vreducess|vreducesd|vpmovm2d|vpmovm2q|vpmovm2b|vpmovm2w|vpmovd2m|vpmovq2m|vpmovb2m|vpmovw2m|vpmullq|vpmadd52luq|vpmadd52huq|v4fmaddps|v4fmaddss|v4fnmaddps|v4fnmaddss|vp4dpwssd|vp4dpwssds|vpdpbusd|vpdpbusds|vpdpwssd|vpdpwssds|vpcompressb|vpcompressw|vpexpandb|vpexpandw|vpshld|vpshldv|vpshrd|vpshrdv|vpopcntd|vpopcntq|vpopcntb|vpopcntw|vpshufbitqmb|gf2p8affineinvqb|gf2p8affineqb|gf2p8mulb|vpclmulqdq|vaesdec|vaesdeclast|vaesenc|vaesenclast)\>/' binary.asm 

(Hinweis: Wenn gawk‚s Wortgrenzen \<und \>arbeiten nicht für Sie, können Sie sie mit einfachen ersetzen [ \t]Es könnte die Skripte funktionieren in anderen Versionen von AWK sowie machen, wie. nawk.)