( ricpet | 2024. 03. 12., k – 13:28 )

Erre elvileg nincs szükség, a betöltő pont azért van. 

Itt arra gondolok, hogyan tudom azt elérni, hogy a Rust által generált output az ne támaszkodjon arra, hogy van oprendszer, ill. van C runtime. Van ehhez opció, csak nyilvánvalóan ez az erősen haladó rész. Ahogy mondtam, ez az első Rust programom. Szóval ez inkább a saját szívásom volt :)

Tessék az AMD és Intel mérnököknél panaszkodni, ne nálam. Így működik a CPU, ezt nem tudod megkerülni. Még Assembly-ben is külön speciális utasítás van erre (aminek a neve történetesen "iretq").

Ezzel én teljes mértékben tisztában vagyok. És semmi hiba nincs a CPU utasításkészletében. Itt csakis abban van a hiba, hogy te hogyan tervezted meg, hogy a megoldás futása során majd meghívódjon az IRETQ utasítás. Arra gondolok, hogy ahelyett, hogy

Magas szintű nyelven írt handler kezdete:
  Implementációs lépések...
  Továbbhívás a bootloader iretq függvényébe
    Bootloader iretq függvény kezdete:
      Magic a stack pointerrel, mert nem tudod, hogy a hívó magas szintű implementáció mekkora stack frame-et csinált
      OUT instruction
      IRETQ instruction
    Bootloader iretq függvény vége
Handler vége

sokkal értelmesebb így csinálni:

Handler kezdete:
  Továbbhívás a magas szintű nyelvi implementációba
    Magas szintű nyelvi implementáció belépési pontja:
      ...
    Magas szintű nyelvi implementáció vége
  OUT instruction
  IRETQ instruction
Handler vége

nem igazán tudod megtippelni, hogy mekkora lesz a stack frame

Egy C program ezen a CPU specifikus működésen túl nem is nyúl a veremhez (amennyiben a függvény nem tartalmaz lokális változót).

Ez tippre nem így van, szerintem lehet olyan bonyolult kifejezéseket csinálni, ahol lokális változó nélkül is muszáj a stack-hez nyúlnia a compilernek. Másik szempont: ha csapatban dolgozol? És bárki hozzáad később egy lokális változót a függvényhez? Akkor mindenki vakarhatja a fejét, hogy mitől fagy le az egész, mert van valahol benne egy magic constant, aminek elmászott az értéke.

És ez teljesen igaz C-re és Rust-ra is. Ez a fajta megközelítés nyelvfüggetelenül szívás. Ahogy mások is írták, akár compiler optimalizációs szinttől is függ. Pl. a Microsoft compiler a CALL helyett JMP hívással megy tovább a bootloader-ed függvényébe, mivel látja, hogy ez a függvény utolsó sora. Úgy itt ezért kellett pl. negatív szám ahhoz, hogy mekkora a stack frame.

Azt akartam ezzel mondani, hogy ez egy értelmesebb méretű rendszernél átgondolandó. A jelen példaprogramnál persze tökmindegy, mondhatni a kihívás része :)