Förstå grenfördröjningsluckor för reversering av MIPS

Jag reverserar statiskt en del programvara som har sammanställts för en Atheros AR7161 med radare2. Denna processor implementerar MIPS, och jag minns att MIPS har en grenfördröjningsplats. Detta märks verkligen vid demonteringen eftersom jag kan se instruktioner som logiskt ska utföras innan filialer placeras direkt efter dem.

Men när jag analyserade en bit kod kom jag över en beqz-instruktion för vilken jag antog att instruktionen efter att den ska genomföras först är inte meningsfull i programmets sammanhang. Jag måste erkänna att min analys kan vara fel, vilket inte är osannolikt. Jag har dock några tvivel om att jag också vill rensa:

  • Gör alla gren- / hoppinstruktioner alltid grenfördröjningsfacket så att instruktionen direkt därefter logiskt ska utföras först ? Om inte, i vilka fall skulle det inte vara det?

  • Finns det något sätt att få radare2 att visa den logiska körningsordningen i stället för den som är kodad i binären?

Redigera : Konkret har jag att göra med följande sekvens:

beqz v0, <some address> lb v0, 0x40(sp) 

Jag har en mycket diffus bild i mitt huvud om att denna instruktion går in i rörledningen. Jag kan föreställa mig att den andra instruktionen hämtas medan den första avkodas; därför bör exekvering av grenfördröjningsfacket faktiskt börja. Greninstruktionen beror dock på att samma register modifieras av instruktionen i grenfördröjningsfacket, så vad kommer att hända? Kommer greninstruktionen att utvärdera tillståndet med det gamla registret va lue, eller den nya uppdaterad av lb?

Tack

Kommentarer

  • Du kan dra nytta av att läsa MIPS-serien av Raymond Chen här: länk Det första svaret är nej (och se länken för mer information). Jag kan ' inte svara på den andra.

Svara

Instruktionen i grenfördröjningsspåret utvärderas efter greninstruktionen (eller hopp). Utförandet av instruktionen i grenfördröjningsfacket påverkar inte utvärderingen av grenförhållandet.

Jag har observerat att grenfördröjningsfacket används för några saker:

  • Sista instruktionen för det grundläggande blocket som leder fram till greninstruktionen
    • Grenprovet beror inte på resultatet av beräkningen av instruktionen för grenfördröjningsluckan
    • Vanligt sett med ovillkorliga hopp / grenar som b, jal
  • Den första instruktionen om fallet genom blocket .
    • Inga biverkningar bör förekomma om filialen tas.
    • Analys visar att det inte behövs några register som påverkas om filialen tas
  • Den första instruktionen om block om grenen tas
    • Om det finns flera vägar till grenmålet kommer denna instruktion troligen att ses flera gånger med de olika grenarna
  • Belastningen av ett villkorligt värde, ofta för returvärden

Denna artikel går i detalj om grenfördröjningsluckor.

Som noterats av Igor håller den ”troliga” versionen av greninstruktionen effekterna av instruktionen i grenfördröjningsluckan endast om instruktionen faktiskt tas.

Svar

  1. Det finns variationer av villkorliga grenar som kallas ”gren [på villkor] troligt”, t.ex.
    • bgezl – Gren på större än eller lika med noll troligtvis
    • beql – Gren på Lika troligt

Dessa instruktioner har en fördröjningsfack men instruktionen i fördröjningsfacket exekveras endast om filialen tas. Om grenen inte tas är instruktionen i fördröjningsfacket inte exekverad ( ogiltig ) .

OBS: dessa instruktioner har tagits bort i version 6 av MIPS Architecture. Det lade också till kompakta variationer av grenar som inte har fördröjningsfack

När det gäller ditt utdrag misstänker jag starkt att filialen använder det gamla registervärdet, men du kan antagligen bekräfta det bara genom att köra den på en faktisk processor.

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *