jaka jest funkcja NOPL na maszynie x86? Wydaje się, że nic nie robi, ale dlaczego zawsze jest w kodzie montażowym?Co robi NOPL w systemie x86?
Odpowiedz
NOP
to jednobajtowa operacja "do niczego", dosłownie "brak operacji". NOPW, NOPL itd. Są równoważnymi do-nothings, ale przyjmują słowo i długie bajty.
np.
NOP // 1byte opcode
NOP // 1byte opcode
jest równoważna robi
NOPW // 2byte opcode.
Są bardzo przydatne dla dopełnienia rzeczy więc sekwencja kodu zaczyna się na konkretnej granicy pamięci, podejmując się kilka bajtów przestrzeni instrukcji, jeszcze nie właściwie robiąc cokolwiek.
jedynym efektem NOP w sprawie CPU jest przyrost IP
/EIP
przez 1. ekwiwalenty NOPx zrobi to przez 2, 4, itd ...
Nigdy nie słyszałem o operacji NOPW i NOPL w zestawie instrukcji x86 .. ani pojawiają się w zestawie instrukcji Intel Instruction :) Może mieszasz różne architektury – Jack
@Jack pachnie jak składnia AT & T do mnie – harold
@harold Nie wiem .. gcc narzeka, jeśli używam nopw/nopl zamiast nop – Jack
Edit: Dodano odniesienia do dokumentacji i gas
gas
kodowań dla różnych nop
formach:
Według John Fremlin's blog: Operands to NOP on AMD64, nopw
, nopl
itp są gas
składni, a nie na & składni T.
Poniżej instrukcja kodowania generowane przez gas
dla różnych nop
„s od gas
source instrukcji dla długościach od 3 do 15 bajtów. Zauważ, że niektóre z nich są takie same jak zalecane przez Intela formularze nop
(patrz poniżej), ale nie wszystkie. W szczególności, już nop
„s gas
wykorzystuje wiele (do 5) kolejnych 0x66
operandów prefiksy w różnych formach nop
, natomiast Intel zaleca nop
formy nigdy nie używać więcej niż jednego 0x66
prefiks argumentu w jakiejkolwiek pojedynczej zalecanej instrukcji nop
.
nop
kodowania z gas
source (przekształcony dla czytelności):
/* nopl (%[re]ax) */
static const char alt_3[] = {0x0f,0x1f,0x00};
/* nopl 0(%[re]ax) */
static const char alt_4[] = {0x0f,0x1f,0x40,0x00};
/* nopl 0(%[re]ax,%[re]ax,1) */
static const char alt_5[] = {0x0f,0x1f,0x44,0x00,0x00};
/* nopw 0(%[re]ax,%[re]ax,1) */
static const char alt_6[] = {0x66,0x0f,0x1f,0x44,0x00,0x00};
/* nopl 0L(%[re]ax) */
static const char alt_7[] = {0x0f,0x1f,0x80,0x00,0x00,0x00,0x00};
/* nopl 0L(%[re]ax,%[re]ax,1) */
static const char alt_8[] = {0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00};
/* nopw 0L(%[re]ax,%[re]ax,1) */
static const char alt_9[] = {0x66,0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00};
/* nopw %cs:0L(%[re]ax,%[re]ax,1) */
static const char alt_10[] = {0x66,0x2e,0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00};
/* data16
nopw %cs:0L(%[re]ax,%[re]ax,1) */
static const char alt_long_11[] = {0x66,0x66,0x2e,0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00};
/* data16
data16
nopw %cs:0L(%[re]ax,%[re]ax,1) */
static const char alt_long_12[] = {0x66,0x66,0x66,0x2e,0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00};
/* data16
data16
data16
nopw %cs:0L(%[re]ax,%[re]ax,1) */
static const char alt_long_13[] = {0x66,0x66,0x66,0x66,0x2e,0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00};
/* data16
data16
data16
data16
nopw %cs:0L(%[re]ax,%[re]ax,1) */
static const char alt_long_14[] = {0x66,0x66,0x66,0x66,0x66,0x2e,0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00};
/* data16
data16
data16
data16
data16
nopw %cs:0L(%[re]ax,%[re]ax,1) */
static const char alt_long_15[] = {0x66,0x66,0x66,0x66,0x66,0x66,0x2e,0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00};
/* nopl 0(%[re]ax,%[re]ax,1)
nopw 0(%[re]ax,%[re]ax,1) */
static const char alt_short_11[] = {0x0f,0x1f,0x44,0x00,0x00,0x66,0x0f,0x1f,0x44,0x00,0x00};
/* nopw 0(%[re]ax,%[re]ax,1)
nopw 0(%[re]ax,%[re]ax,1) */
static const char alt_short_12[] = {0x66,0x0f,0x1f,0x44,0x00,0x00,0x66,0x0f,0x1f,0x44,0x00,0x00};
/* nopw 0(%[re]ax,%[re]ax,1)
nopl 0L(%[re]ax) */
static const char alt_short_13[] = {0x66,0x0f,0x1f,0x44,0x00,0x00,0x0f,0x1f,0x80,0x00,0x00,0x00,0x00};
/* nopl 0L(%[re]ax)
nopl 0L(%[re]ax) */
static const char alt_short_14[] = {0x0f,0x1f,0x80,0x00,0x00,0x00,0x00,0x0f,0x1f,0x80,0x00,0x00,0x00,0x00};
/* nopl 0L(%[re]ax)
nopl 0L(%[re]ax,%[re]ax,1) */
static const char alt_short_15[] = {0x0f,0x1f,0x80,0x00,0x00,0x00,0x00,0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00};
Intel używa innej składni, a istnieją nop
„s dostępne dla wszystkich długościach instrukcje od 1 do 9 bajtów. Istnieje kilka różnych nop
, ponieważ wszystkie nop
dłuższe niż dwa bajty akceptują 1 operand. One-byte nop
(0x90
) jest równoznaczne z xchg (e)ax,(e)ax
.
Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 2 (2A, 2B & 2C): Instruction Set Reference, A-Z, CHAPTER 4: INSTRUCTION SET REFERENCE, M-Z list polecany nop
formy dla różnych długościach instrukcje:
Table 4-12. Recommended Multi-Byte Sequence of NOP Instruction
Length Assembly Byte Sequence
2 bytes 66 NOP 66 90H
3 bytes NOP DWORD ptr [EAX] 0F 1F 00H
4 bytes NOP DWORD ptr [EAX + 00H] 0F 1F 40 00H
5 bytes NOP DWORD ptr [EAX + EAX*1 + 00H] 0F 1F 44 00 00H
6 bytes 66 NOP DWORD ptr [EAX + EAX*1 + 00H] 66 0F 1F 44 00 00H
7 bytes NOP DWORD ptr [EAX + 00000000H] 0F 1F 80 00 00 00 00H
8 bytes NOP DWORD ptr [EAX + EAX*1 + 00000000H] 0F 1F 84 00 00 00 00 00H
9 bytes 66 NOP DWORD ptr [EAX + EAX*1 + 00000000H] 66 0F 1F 84 00 00 00 00 00H
Więc oprócz tych nop
's rekomendowanych przez firmę Intel, istnieje wiele innych nop
' s zbyt. Oprócz dopasowania instrukcji do określonej granicy pamięci, jak wspomina Marc B w swojej odpowiedzi, nop
są również bardzo użyteczne w korygowaniu samego kodu, debugowaniu i inżynierii wstecznej.
Zauważ, że na amd64 'nop' nie jest już równoznaczny z' xchg eax, eax'. 'nop' nie wyzerowuje 32 najlepszych bitów' eax', ale 'xchg eax, eax' robi. – fuz
W rzeczywistości NOP zostanie użyty w kodzie zespołu, gdy kod będzie wymagał poprawki.
Ponieważ rozmiar nowej instrukcji może różnić się od starej, konieczne jest wypełnienie.
Instrukcja wypełniania powinna zachowywać się tak samo, jak NOP, chociaż może zajmować kilka bajtów.
Powodem, dla którego wstawiamy bardziej złożoną instrukcję, np. 66 90, zamiast kilku NOP, jest jedna instrukcja generalnie wykonywana szybciej niż kilka NOP.
- 1. Dlaczego instrukcja nopl x86 przyjmuje operand?
- 2. Co robi ten wbudowany procesor x86?
- 3. Co robi sekwencja instrukcji składania "rep stos" x86?
- 4. Co robi * w CSS?
- 5. Co robi% w JavaScript?
- 6. Co Boxen i co robi?
- 7. Co robi znak @ w jQuery?
- 8. Co robi \ 1 w sed?
- 9. Co robi Collections.unmodifiableSet() w Javie?
- 10. Co robi symbol "@" w Powershell?
- 11. Co robi session_destroy() w PHP?
- 12. Co robi? zrobić w Elixir
- 13. Co robi `` ... znaczy w idź
- 14. Co robi rebaseall w Cygwin?
- 15. Co robi "^: static" w Clojure?
- 16. Co [[]] * 2 robi w pythonie?
- 17. Co robi config.gem (w environment.rb)?
- 18. Co {} robi w ciągu znaków?
- 19. Co robi dodatkowy przycisk "$()" w "$ ($())"?
- 20. Co robi% w poniższym kodzie?
- 21. co robi int() w C++?
- 22. Co robi * ~ w pliku .gitignore?
- 23. Co robi autoload w zsh?
- 24. Co robi <() w Bash?
- 25. Co robi "%% DatabaseEx" w TSQL?
- 26. Co robi DELIMITER // w wyzwalaczu?
- 27. Co robi "Force" w Unecrustify?
- 28. Co robi `session.entropy_length` w` PHP.ini`?
- 29. Co robi mysqld_safe w my.cnf?
- 30. Co robi opt.apply_gradients() w TensorFlow?
Pytasz "dlaczego jest zawsze w kodzie zespołu?" - zazwyczaj nie znajdujesz wielu NOP-ów w kodzie zespołu. Czy jakiś konkretny kod, który przeglądasz, ma wiele NOPów? – ugoren
Człowieku, chciałbym móc "poczuć", co robi kod! –
http://stackoverflow.com/questions/6776385/what-is-faster-jmp-or-string-of-nops/6777644 –