I did a “lecture”/“workshop” about this at work today. 16-bit DOS, real mode. đŸ’Ÿ Pretty cool and the audience (devs and sysadmins) seemed quite interested. đŸ„ł

  • People used the Intel docs to figure out the instruction encodings.
  • Then they wrote a little DOS program that exits with a return code and they used uhex in DOSBox to do that. Yes, we wrote a COM file manually, no Assembler involved. (Many of them had never used DOS before.)
  • DEBUG from FreeDOS was used to single-step through the program, showing what it does.
  • This gets tedious rather quickly, so we switched to SVED from SvarDOS for writing the rest of the program in Assembly language. nasm worked great for us.
  • At the end, we switched to BIOS calls instead of DOS syscalls to demonstrate that the same binary COM file works on another OS. Also a good opportunity to talk about bootloaders a little bit.
  • (I think they even understood the basics of segmentation in the end.)

The 8086 / 16-bit real-mode DOS is a great platform to explain a lot of the fundamentals without having to deal with OS semantics or executable file formats.

Now that was a lot of fun. đŸ„ł It’s very rare that we do something like this, sadly. I love doing this kind of low-level stuff.


#xabos5a

(#gg4pbpa) (Of course, if we’re talking about a project you’re doing for a customer and the customer keeps asking for new stuff, then you’re never done, and you have to think ahead and expect changes. Is that what they mean? đŸ€”)


#vpk5iga

Saw this on Mastodon:

https://racingbunny.com/@mookie/114718466149264471

18 rules of Software Engineering

  1. You will regret complexity when on-call
  2. Stop falling in love with your own code
  3. Everything is a trade-off. There’s no “best” 3. Every line of code you write is a liability 4. Document your decisions and designs
  4. Everyone hates code they didn’t write
  5. Don’t use unnecessary dependencies
  6. Coding standards prevent arguments
  7. Write meaningful commit messages
  8. Don’t ever stop learning new things
  9. Code reviews spread knowledge
  10. Always build for maintainability
  11. Ask for help when you’re stuck
  12. Fix root causes, not symptoms
  13. Software is never completed
  14. Estimates are not promises
  15. Ship early, iterate often
  16. Keep. It. Simple.

Solid list, even though 14 is up for debate in my opinion: Software can be completed. You have a use case / problem, you solve that problem, done. Your software is completed now. There might still be bugs and they should be fixed – but this doesn’t “add” to the program. Don’t use “software is never done” as an excuse to keep adding and adding stuff to your code.


#gg4pbpa

Okay, here’s a thing I like about Rust: Returning things as Option and error handling. (Or the more complex Result, but it’s easier to explain with Option.)

fn mydiv(num: f64, denom: f64) -> Option<f64> {
    // (Let’s ignore precision issues for a second.)
    if denom == 0.0 {
        return None;
    } else {
        return Some(num / denom);
    }
}

fn main() {
    // Explicit, verbose version:
    let num: f64 = 123.0;
    let denom: f64 = 456.0;
    let wrapped_res = mydiv(num, denom);
    if wrapped_res.is_some() {
        println!("Unwrapped result: {}", wrapped_res.unwrap());
    }

    // Shorter version using "if let":
    if let Some(res) = mydiv(123.0, 456.0) {
        println!("Here’s a result: {}", res);
    }

    if let Some(res) = mydiv(123.0, 0.0) {
        println!("Huh, we divided by zero? This never happens. {}", res);
    }
}

You can’t divide by zero, so the function returns an “error” in that case. (Option isn’t really used for errors, IIUC, but the basic idea is the same for Result.)

Option is an enum. It can have the value Some or None. In the case of Some, you can attach additional data to the enum. In this case, we are attaching a floating point value.

The caller then has to decide: Is the value None or Some? Did the function succeed or not? If it is Some, the caller can do .unwrap() on this enum to get the inner value (the floating point value). If you do .unwrap() on a None value, the program will panic and die.

The if let version using destructuring is much shorter and, once you got used to it, actually quite nice.

Now the trick is that you must somehow handle these two cases. You must either call something like .unwrap() or do destructuring or something, otherwise you can’t access the attached value at all. As I understand it, it is impossible to just completely ignore error cases. And the compiler enforces it.

(In case of Result, the compiler would warn you if you ignore the return value entirely. So something like doing write() and then ignoring the return value would be caught as well.)


#a4qstxa

(#xfrwj3q) @aelaraji@aelaraji.com I use Alt+. all the time, it’s great. 👌

FWIW, another thing I often use is !! to recall the entire previous command line:

$ find -iname '*foo*'
./This is a foo file.txt

$ cat "$(!!)"
cat "$(find -iname '*foo*')"
This is just a test.

Yep!

Or:

$ ls -al subdir
ls: cannot open directory 'subdir': Permission denied

$ sudo !!
sudo ls -al subdir
total 0
drwx------ 2 root root  60 Jun 20 19:39 .
drwx------ 7 jess jess 360 Jun 20 19:39 ..
-rw-r--r-- 1 root root   0 Jun 20 19:39 nothing-to-see

#c6wcloa

(#xfrwj3q) @aelaraji@aelaraji.com Oh, that’s great! I haven’t heard about any of them before either. There’s also a caveat though, that I ran right into the very first time I tried this in zsh:

$ ls > /dev/null
$ echo $_
--color=tty

Yeah, exactly what you think:

$ which ls
ls: aliased to ls --color=tty

Alt+. is going to be my favorite one! In the above, it would also give me /dev/null, which might be probably more what I would expect.


#g6omxpq

(#y36ebpa) @kat@yarn.girlonthemoon.xyz I guess that qualifies as an “Arch moment”, albeit the first one I encountered. I’m running this since 2008 and it’s usually very smooth sailing. 😅

@lyse@lyse.isobeef.org Yeah, YMMV. Some games work(ed) great in Wine, others not at all. I just use it because it’s easier than firing up my WinXP box. (I don’t use Wine for regular applications, just games.)


#luv4l6q

I probably should implement some editing feature in tt. Sure, I can easily edit my feed in vim to fix typos. But then I still have to manually remove the old message from the cache so that the new message is inserted on next reload and I don’t end up with “duplicates” in the message tree.


#xu7z3za

(#v7d7d4a) @movq@www.uninformativ.de That sounds great! (Well, they actually must have recorded the audio with a potato or so.) You talked about pledge(
) and unveil(
) before, right? I somewhere ran across them once before. Never tried them out, but these syscalls seem to be really useful. They also have the potential to make one really rethink about software architecture. I should probably give this a try and see how I can improve my own programs.


#l4vun6q

been a while! i’ve been using my laptop more to kind of change my workflow, but without my browser bookmarks to remind me to check some sites, i’ve forgotten to check yarnverse! forgive me friends T_T


#wkff76a

j’ai un souci avec mon nouveau routeur : depuis mon rĂ©seau local, lorsque je veux rejoindre mon serveur via son ip publique, ça me renvoie sur le routeur et ne redirige pas vers la DMZ comme ça le fait lorsque je suis en dehors du LAN. Des idĂ©es? C’est un zyxel


#dwx23rq

À la fin de mes Ă©valuations, j’aime bien y mettre une petite #quote. Celle d’aujourd’hui c’est : Si ça ne marche plus, je le rĂ©pare. Si je sais pas le rĂ©parer, j’apprends. Si ça n’existe pas, je le crĂ©e. Si je ne sais pas comment crĂ©er, j’expĂ©rimente. SolĂšne Rapenne, experte informatique  (1989 – )


#s3v5bdq