Inline-Montage, die den roten Bereich überdeckt

Lesezeit: 3 Minuten

Benutzer-Avatar
Mike Hamburg

Ich schreibe ein Kryptographieprogramm, und der Kern (eine breite Multiplikationsroutine) ist in x86-64-Assembler geschrieben, sowohl wegen der Geschwindigkeit als auch weil es Anweisungen wie z adc die von C aus nicht leicht zugänglich sind. Ich möchte diese Funktion nicht einbetten, weil sie groß ist und mehrmals in der inneren Schleife aufgerufen wird.

Idealerweise möchte ich auch eine benutzerdefinierte Aufrufkonvention für diese Funktion definieren, da sie intern alle Register verwendet (außer rsp), überschreibt seine Argumente nicht und gibt in Registern zurück. Im Moment ist es an die C-Aufrufkonvention angepasst, aber das macht es natürlich langsamer (um etwa 10%).

Um dies zu vermeiden, kann ich es mit aufrufen asm("call %Pn" : ... : my_function... : "cc", all the registers); aber gibt es eine Möglichkeit, GCC mitzuteilen, dass die Aufrufanweisung den Stack durcheinander bringt? Andernfalls setzt GCC all diese Register einfach in den roten Bereich, und das oberste wird platt gemacht. Ich kann das gesamte Modul mit -mno-red-zone kompilieren, aber ich würde es vorziehen, GCC mitzuteilen, dass beispielsweise die obersten 8 Bytes der roten Zone überschrieben werden, damit dort nichts abgelegt wird.

  • Nur eine ungetestete, aber können Sie nicht einfach eine zusätzliche Dummy-Eingabe angeben, sodass GCC sie in den roten Bereich versetzt und (harmlos) verprügelt wird?

    – Toni Delroy

    17. Juni 2011 um 5:55 Uhr

  • Hm. Vermutlich nicht zuverlässig. Ich habe festgestellt, dass es ziemlich schwierig ist, zu kontrollieren, was GCC wann und wo auf den Stack überträgt. Bei anderem Krypto-Zeug, das ich geschrieben habe, habe ich mit gemischtem Erfolg versucht, die Tendenz von GCC zu unterdrücken, zB ganze Schlüsseltabellen ohne Grund auf den Stack zu schreiben.

    – Michael Hamburg

    18. Juni 2011 um 7:49 Uhr

  • Hinzufügen sp als Klamotten? Einen Speicher-Clobber hinzufügen?

    – tc.

    22. März 2013 um 16:55 Uhr

  • Wie wäre es, wenn Sie die Krypto-Routine als Makro definieren (unter Verwendung von Top-Level-Asm am Anfang der Datei)? Wenn Sie es dann aufrufen (im Gegensatz zu calling) von mehreren Stellen innerhalb Ihres C-Codes über erweitertes asm ist etwas weniger schrecklich (obwohl es die ausführbare Datei aufbläht). Sie können immer noch alle Register überschreiben, aber der Stack ist davon nicht betroffen. Übrigens, woher weiß die Krypto, was sie verschlüsseln soll? Der Zugriff auf Globals über Inline kann schwierig sein. Auch Clobbering SP hat Kein Effekt.

    – David Wohlferd

    27. Juni 2016 um 1:41 Uhr

  • Es gibt __attribute__(leaf) aber leider gibt es nichts dergleichen __attribute__(nonleaf)

    – Ben Voigt

    18. Juni 2011 um 20:57 Uhr

  • Ich finde es nicht schockierend, dass gcc die Red-Zone nicht aufgibt, wenn es Stack-Platz reservieren muss: Einer der Vorteile der Red-Zone ist, dass man mit disp8-Displacements mehr Speicher erreichen kann, also mit rsp mitten unter den Einheimischen bedeutet, dass es alle erreichen kann [rsp-128..+127] Adressierungsmodi. Es ist eine gute Optimierung. (Oder es wäre gewesen, wenn Sie verwendet hätten -O3 + volatile char buf[150] um stattdessen einen RSP-relativen Adressierungsmodus zu erhalten -155(%rbp))

    – Peter Cordes

    20. Februar 2018 um 0:31 Uhr

  • Ich kann es nicht innerhalb der Funktion selbst tun, weil call verwendet den Stapel und macht daher Dinge von selbst kaputt. sub $128, %rsp; call...; add $128, %rsp funktioniert, ist aber alles andere als ideal. Ich schätze, insgesamt ist es wahrscheinlich am besten, wenn meine Funktion dem ABI entspricht.

    – Michael Hamburg

    18. Juni 2011 um 7:44 Uhr

  • Und markieren Sie diese Funktion als __attribute__((noinline))? Mit -O0kann der Compiler immer noch Funktionsargumente in die rote Zone übertragen.

    – Peter Cordes

    21. Dezember 2017 um 15:23 Uhr

  • Und markieren Sie diese Funktion als __attribute__((noinline))? Mit -O0kann der Compiler immer noch Funktionsargumente in die rote Zone übertragen.

    – Peter Cordes

    21. Dezember 2017 um 15:23 Uhr

1345590cookie-checkInline-Montage, die den roten Bereich überdeckt

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy