Blog

  • Everlasting Love Podcast Index

    The official YouTube channel under Judena’s account is the best place to search for and find our episodes. However, because YouTube can be a bit confusing to navigate and sometimes changes, I have provided this index of episodes in the order they were recorded, along with their YouTube link.

    Official YouTube Channel:

    https://www.youtube.com/@EverlastingLoveJeremiah31-3

    Everlasting Love Episode 1: Introduction

    Judena Klebs and her hybrid son/daughter, Chastity, give a short introduction to our podcast and what we will be talking about in future episodes.

    https://www.youtube.com/watch?v=HkOnRJnLujQ


    Everlasting Love Episode 2: Asexuality and Transgender Identity

    In this episode, Judena Klebs and Chastity White Rose define terms and look at scriptures about eunuchs in the Bible.

    https://www.youtube.com/watch?v=iv6qEXTdxYM


    Everlasting Love Episode 3: Transgender Concerns

    Judena and Chastity talk about various concerns like gendered bathroom laws, equality in sports, the history of sexism, and how we should all be equal as stated in Galatians 3:28.

    Galatians 3:28 There is neither Jew nor Greek, there is neither slave nor free, there is neither male nor female–for all of you are one in Christ Jesus.

    https://www.youtube.com/watch?v=6BQyVwF-gvk


    Everlasting Love Episode 4: Understanding Depression and Suicide

    Judena and Chastity share past experiences with depression and suicidal thoughts. Many times, people condemn people with mental health struggles and make the problems worse. However, in the minds of depressed people, they often feel like they are doing the world a favor and have nothing to offer. But this is not true. God loves them and so do people, including those who they have not met yet.

    https://www.youtube.com/watch?v=utb98jllO98


    Everlasting Love Episode 5: Jesus’ Command of Love for His Church

    The true church of God’s people is not a building. It is made up of God’s people who have come to Christ for salvation.

    https://www.youtube.com/watch?v=ndBkPfUbkMY


    Everlasting Love Episode 6: The People of God and the Rainbow Bridge

    All the religions of the world are humanity’s effort to reach God and appease him except for true Christianity. It is God reaching out to humankind and coming to save and relate to them.

    https://www.youtube.com/watch?v=sj0ryRkRrEw

    You can read the currently available chapters of “Walking the Rainbow Bridge” at the following links.

    https://chastitywhiterose.com/walking-the-rainbow-bridge/

    https://chastitywhiterose.github.io/Walking-the-Rainbow-Bridge/

    You can also buy the republished paperback of Chandler’s Honesty containing all 6 parts of the story.

    https://www.amazon.com/gp/product/B0FNLRS2D4

    Everlasting Love Episode 7: Alphabet Acronym and “Abomination”

    In this episode, we defined the letters of the LGBTQIA+ acronym, and then we talked about the historical meaning of the words that were later translated into homosexuality and abomination.

    Finally, we discussed other issues that people falsely assume about LGBTQIA+ people. For example, People assume that LGBTQIA+ individuals all support abortion or that all transgender people are school shooters.

    https://www.youtube.com/watch?v=0so6NCeRSV8

    Everlasting Love Episode 8: Resources and excerpts on LGBTQIA+ and Suicide Prevention

    In this episode, we shared some quotes from the Bible and also some very relevant books written by other authors, which will be helpful to Christians who are on the LGBTQIA+ spectrum.

    https://www.youtube.com/watch?v=2avMdLQsdGU

    3 of these books are also linked to in Chastity’s 6th chapter of Walking the Rainbow Bridge.

    https://chastitywhiterose.com/2025/06/17/chapter-6-can-someone-be-gay-and-a-christian/

    Also, we have published a book on The Many Sides of Suicide:

    https://www.amazon.com/Many-Sides-Suicide-Judena-Klebs/dp/B092P62TRR/

    Everlasting Love Episode 9: When God Finds YOU

    Judena and Chastity share their stories of how they came to believe in God despite being given wrong messages by humans. Sometimes people are searching for God, and sometimes they give up, but even then, God will go to find the lost sheep.

    https://www.youtube.com/watch?v=aS8pyjb2Dpw

    Everlasting Love Episode 10: Two Kingdoms: A Teaching About Spiritual Warfare

    Judena introduces the topic of Spiritual Warfare and shares her experience and some Bible verses for historical context on Satan and the demons. Chastity asks Judena some questions she has and suspects others may want to ask about these things.

    https://www.youtube.com/watch?v=1m06bHaZq9s

    Relevant Verses:

    John 10:10 Ephesians 6:12 James 4:7 1 Peter 5:2-9

    Everlasting Love Episode 11: Spiritual Warfare Continued

    Judena and Chastity continue their discussion on spiritual warfare and some background information on Lucifer/Satan/Devil.

    https://www.youtube.com/watch?v=Kolh2QstXt8

    Bible Verses:

    Revelation 12:7-10 Isaiah 14:12-17 Ezekiel 28:12-19 Luke 10:17-20

    2 Corinthians 4:4 2 Corinthians 11:14 Hebrews 2:14-18

    Everlasting Love Episode 12: Halloween

    Judena and Chastity discuss the history of Halloween and good elements that should be enjoyed at other times of year, and bad elements that could be replaced with something healthier and celebrating life instead.

    https://www.youtube.com/watch?v=z1o-cDhvXdc

    Everlasting Love Episode 13: Halloween Part 2

    Occult practices promoted by Halloween and why they are dangerous.

    https://www.youtube.com/watch?v=UMkc3ODoX1w

    Referenced Verses

    Exodus: 5:1 And afterward Moses and Aaron went in, and told Pharaoh, Thus saith the LORD God of Israel, Let my people go, that they may hold a feast unto me in the wilderness.

    2 And Pharaoh said, “Who is the LORD, that I should obey his voice to let Israel go? I know not the LORD, neither will I let Israel go .”

    "Exodus 7:8 And the LORD spake unto Moses and unto Aaron, saying,

    9 When Pharaoh shall speak unto you, saying, Shew a miracle for you: then thou shalt say unto Aaron, Take thy rod, and cast it before Pharaoh, and it shall become a serpent.

    10 And Moses and Aaron went in unto Pharaoh, and they did so as the LORD had commanded: and Aaron cast down his rod before Pharaoh, and before his servants, and it became a serpent.

    11 Then Pharaoh also called the wise men and the sorcerers: now the magicians of Egypt, they also did in like manner with their enchantments.

    12 For they cast down every man his rod, and they became serpents: but Aaron’s rod swallowed up their rods."


    Everlasting Love Episode 14: Admitting When We Are Wrong

    How important our words are and the influence we have. It is important to set a good example and admit the times when we are wrong in what we said.

    https://www.youtube.com/watch?v=4AxHVp9NqIo


    Everlasting Love Episode 15: How to Help Ourselves and Others with Depression

    Special guest Lauren joins us and speaks about her experience with depression and what helps.

    https://www.youtube.com/watch?v=AnYI93mxqVg

    Everlasting Love Episode 16: “Christian” Hypocrisy

    Often God can work through non-Christians better than people who claim to be Christians because often Christians have bad attitudes that don’t reflect Christ.

    When God tells us to help someone, we just need to obey God and leave the results to him and not demand something in return.

    We need to minister to the people on the earth the way Jesus did, instead of looking for something in return and manipulating others to do what we want them to do. Simply obey God and show people through what we say and do what God is like.

    https://www.youtube.com/watch?v=vnYoq3zeFuw

    Everlasting Love Episode 17: Grief and the Holidays

    Dealing with grief over the holidays and showing compassion to others who are grieving too.

    https://www.youtube.com/watch?v=7wflDRjJEGs

    Everlasting Love Episode 18: Pro-Life Thoughts and Convictions

    Chastity and Judena talk about Chastity’s upcoming trip to the March for Life and why the topic of abortion is so important to Chastity, because it connects with every other social justice matter of life and death.

    https://www.youtube.com/watch?v=dUDZVgQSLzQ

    Proverbs 31:8+9:

    8 Speak up for those who cannot speak for themselves; ensure justice for those being crushed. 9 Yes, speak up for the poor and helpless, and see that they get justice.

    https://chastitywhiterose.com/2026/01/08/plans-for-march-for-life-2026/

    Everlasting Love Episode 19: Pro-Life Thoughts Part 2

    Chastity tells what happened on her trip to the March for Life in Washington, D.C., and then Judena and Chastity both talk more about why the abortion topic is so important and is shaped by our beliefs and influences around us.

    https://www.youtube.com/watch?v=s6Yc9lAwcgI

    1 John 1:9 “If we confess our sins, He is faithful and just to forgive us our sins and to cleanse us from all unrighteousness.”

    Everlasting Love Episode 20: The Honest Truth

    Chastity and Judena talk about the red herring and other logical fallacies that distract from the topic being discussed and lead to dishonest communication by bringing up new subjects that have no relevance to what you were talking about in the first place.

    https://www.youtube.com/watch?v=p6r53K0hdmY

    Matthew 5:33-37 “33 “Again, you have heard that it was said to an older generation, ‘Do not break an oath, but fulfill your vows to the Lord.’ 34 But I say to you, do not take oaths at all—not by heaven because it is the throne of God, 35 not by earth because it is his footstool, and not by Jerusalem because it is the city of the great King. 36 Do not take an oath by your head because you are not able to make one hair white or black. 37 Let your word be ‘Yes, yes’ or ‘No, no.’ More than this is from the evil one.”

    https://netbible.org/bible/Matthew+5

    Everlasting Love Episode 21 “Does this dress make me look fat?” – The “Double Barreled” Question.

    Some questions cannot be answered with a yes or a no. Chastity and Judena talk about some of these questions and why some questions are dishonest from the start, because someone is forced to lie if they answer yes or know.

    https://www.youtube.com/watch?v=NQr_Q8JzXjA

    Chastity also reads Amendment 3 because it is worded to combine two separate topics, which should have been different amendments, instead of being rolled into one when the topics are unrelated.

    "A double-minded man is unstable in all his ways. (James 1:8)

    Everlasting Love Episode 22: What is God Like?

    Looking at the Bible’s message concerning the character of God.

    https://www.youtube.com/watch?v=d7zooSQc1Vk

    Everlasting Love Episode 23: Should We Fear God?

    When the English translations of the Bible use the word fear, they are not talking about what fear means to us today.

    https://www.youtube.com/watch?v=gfMiDM2IwOk

    Everlasting Love Episode 24: What Does it Mean to Trust God?

    Judena and Chastity talk about the different meanings of faith and trust. These things can sometimes be confusing, but become clearer when understanding who a person is, even if that person is God.

    And for some, God is not always human but may be something else they can trust when they can no longer trust humans.

    https://www.youtube.com/watch?v=A4P0FC8oY7Y

    Everlasting Love Episode 25 “Easter-anity”

    What is Easter? Is it a time once a year to visit a church that you don’t bother to visit most other Sundays, if at all, throughout the year? Is it a time to buy new clothes and put on a fashion show at a building and see who looks the best?

    https://www.youtube.com/watch?v=xWh4WWOhAaY

    Everlasting Love Episode 26: “Easter-anity” Part 2

    Judena and Chastity talk about the greed and competition of modern churches that directly contradict the teachings of Jesus and often lead to idolatry as they claim ownership of truth and even copyright on the Bible.

    https://www.youtube.com/watch?v=hHflQ-UqPBs

    Everlasting Love Episode 27: Sacrifice

    What is sacrifice? Giving what is important and valuable to us in order to serve God and to provide for the needs of others.

    https://www.youtube.com/watch?v=T0o4GB2zhMw

    The Rich Young Man

    Matthew 19:16 Now someone came up to him and said, “Teacher, what good thing must I do to gain eternal life?” 17 He said to him, “Why do you ask me about what is good? There is only one who is good. But if you want to enter into life, keep the commandments.” 18 “Which ones?” he asked. Jesus replied, “Do not murder, do not commit adultery, do not steal, do not give false testimony, 19 honor your father and mother, and love your neighbor as yourself.” 20 The young man said to him, “I have wholeheartedly obeyed all these laws. What do I still lack?” 21 Jesus said to him, “If you wish to be perfect, go sell your possessions and give the money to the poor, and you will have treasure in heaven. Then come, follow me.” 22 But when the young man heard this, he went away sorrowful, for he was very rich.

    The Sacrifice of Isaac

    22 Some time after these things, God tested Abraham. He said to him, “Abraham!” “Here I am!” Abraham replied. 2 God said, “Take your son—your only son, whom you love, Isaac—and go to the land of Moriah! Offer him up there as a burnt offering on one of the mountains which I will indicate to you.”

    3 Early in the morning, Abraham got up and saddled his donkey. He took two of his young servants with him, along with his son Isaac. When he had cut the wood for the burnt offering, he started out for the place God had spoken to him about.

    4 On the third day, Abraham caught sight of the place in the distance. 5 So he said to his servants, “You two stay here with the donkey while the boy and I go up there. We will worship and then return to you.”

    6 Abraham took the wood for the burnt offering and put it on his son Isaac. Then he took the fire and the knife in his hand, and the two of them walked on together. 7 Isaac said to his father Abraham, “My father?” “What is it, my son?” he replied. “Here is the fire and the wood,” Isaac said, “but where is the lamb for the burnt offering?” 8 “God will provide for himself the lamb for the burnt offering, my son,” Abraham replied. The two of them continued on together.

    9 When they came to the place God had told him about, Abraham built the altar there and arranged the wood on it. Next, he tied up his son Isaac and placed him on the altar on top of the wood. 10 Then Abraham reached out his hand, took the knife, and prepared to slaughter his son. 11 But the angel of the Lord called to him from heaven, “Abraham! Abraham!” “Here I am!” he answered. 12 “Do not harm the boy!” the angel said. “Do not do anything to him, for now I know that you fear God because you did not withhold your son, your only son, from me.”

    13 Abraham looked up and saw behind him a ram caught in the bushes by its horns. So he went over and got the ram and offered it up as a burnt offering instead of his son. 14 And Abraham called the name of that place “The Lord provides.” It is said to this day, “In the mountain of the Lord provision will be made.”

    Everlasting Love Episode 28: Connecting with Jesus

    If Jesus is the head of the church, we can’t function as a living organism as his body, the church, without being and staying connected with him.

    https://www.youtube.com/watch?v=eNLuR2bJ4Ts

    Everlasting Love Episode 29: Perseverance

    When the Bible uses the word “patience”, it means perseverance or endurance in the way we talk today.

    https://www.youtube.com/watch?v=H-cN2NuEe2I

    Everlasting Love Episode 30: LGBTQIA+ Part 1 Preparing for “Pride Month”

    We are going to start a series today to cover many of the topics we promised to deal with regarding the LGBTQIA+ community.

    https://www.youtube.com/watch?v=H-cN2NuEe2I

    Everlasting Love Episode 31: LGBTQIA+ Part 2: Attitudes about Gender in the book of Genesis

    Second part of the series for Pride Month 2026.

    https://www.youtube.com/watch?v=suFmcYn5L_s&pp=0gcJCaMLAYcqIYzv

    Everlasting Love Episode 32: LGBTQIA+ Part 3: Laws and Abominations

    • Define Abomination
    • Various Laws that were called Abominations
    • Are some sins worse than others
    • What is sin?
    • Picking out sin that are popular to criticize by heterosexual people, but ignoring others that were considered as abominations.

    https://www.youtube.com/watch?v=Dan0qFOhktI

    Everlasting Love Episode 33: LGBTQIA+ Part 4: The Purpose of the Law

    Chastity and Judena talk about the importance of understanding what the law is for and the reasons why old testament laws were given. Too often, people just use them as a weapon against people and say they are bad for breaking laws from the same book that the accuser doesn’t live by to begin with.

    https://www.youtube.com/watch?v=Magt-rnyYAg

    Everlasting Love Episode 34 LGBTQIA+ Part 5: The word “homosexual”

    Historical background of how this word came to be invented and mistakenly added to the Bible.

    https://www.youtube.com/watch?v=6i86oMG_srg

    Everlasting Love Episode 35: Dealing with Depression

    Lauren Pundmann joins us for a deeper look at depression.

    https://www.youtube.com/watch?v=J6rc2l2mfls

  • Getting Started with Linux

    This is chapter 19 of my Linux Assembly book. However, it has a ton of information about Linux in general. I also cover how to run the Tiny Core Linux distribution inside of the QEMU emulator. This will give current Windows users a way to try out Linux without having to give up Windows until they are sure they no longer need it. Even if you don’t plan to do Assembly programming, this is a great way to get a retro computing feel because a terminal only Linux system is very similar to DOS, except the names of all the commands are different!

    Chapter 19: Getting Started with Linux

    This whole book was written on Debian version 12 (bookworm). This has been my Linux distribution on my desktop computer since at least 2024 when Microsoft Windows decided to overwrite my bootloader when I had a dual boot between Windows and Ubuntu. I installed the newest version of Debian available at the time and have never looked back.

    I got my start in the Linux world back in 2005 during the time of Ubuntu 5.10 (Breezy Badger). Ubuntu was my first distribution and I used it without problem for years. But since Ubuntu was based on Debian, I decided to go with the original distribution. I highly recommend either of them because both of these projects have great websites with detailed installation guides.

    https://www.debian.org/
    https://ubuntu.com/

    If you have an old machine running Windows but it is kind of slow, I recommend following the official instructions and installing one of these distributions of Linux to your hard disk by booting either a live CD or USB drive and following the instructions. I figured it out with no background in Linux when I was 18 years old. They have done great work making Linux easy for beginners.

    But what I am going to do is share a method of trying out Linux for people who don’t have a space computer in their house and they can’t risk deleting Windows because their job or school requires specific Windows software.

    Just as I used a DOS emulator to emulate DOS for the DOS edition of Assembly Arithmetic Algorithms, it is also possible to run Linux in an emulator.

    There are some things you should know about running Linux in an emulator.

    1. Emulators are slower than real hardware and cannot be used to judge Linux. Just because you ran Linux in an emulator and it was slow does not mean that the operating system is a failure or that you should give up the idea.

    2. Emulators have many different options that you should read about and the reason I recommend learning how to use an emulator is because it teaches you to understand hardware better. Files are used as virtual compact disks or hard disks but the emulators see them as being the same as real hardware.

    3. Portability is the best reason to use an emulator. Because an emulator can run software for the same machine type or even a different architecture, you can use the information in this book even if you are running an Intel emulator on an ARM or RISC-V processor.

    The emulator I will be using for this example is called QEMU.

    https://www.qemu.org/
    https://www.qemu.org/docs/master/system/invocation.html

    And the distro I will be using is called Tiny Core Linux.

    http://tinycorelinux.net/

    You will want to go to the downloads page and get the smallest of the three files. It will be named “Core-current.iso”.

    Install QEMU on whatever OS you are currently using. QEMU is available for Windows, Mac, and Linux.

    Once you have QEMU installed and downloaded “Core-current.iso” to a directory somewhere, you can launch it with QEMU by using this command.

    qemu-system-x86_64 -drive file=Core-current.iso,media=cdrom
    

    You can also use the shorter form of the command which means the same thing.

    qemu-system-x86_64 -cdrom Core-current.iso
    

    Either way, it will boot into a tiny Linux system that is only a command line. You can use standard Linux commands such as ls,cat,sed,cp,rm,cd, and exit. There is even the “vi” editor built in. If you have not used the vi or vim editors before, don’t worry about it. However, if you have used them, go ahead and practice by making some text files and saving them.

    When you are done using Tiny Core Linux, just use this command:

    sudo poweroff
    

    How does Tiny Core work?

    Everything will shut down and the emulator will also stop. If you clicked on the QEMU Window and your mouse cursor disappeared, press Ctrl+Alt+G on your keyboard to grab it back from the emulator so you can do other things while the emulator is still running Tiny Core Linux.

    Tiny Core Linux runs entirely in RAM when you run it using only the ISO image for the cdrom drive. Any changes you make will not be saved when you exit the emulator.

    I am sure you are wondering what good an operating system is that doesn’t save your work. For that, I have 2 answers.

    1. Because Tiny Core starts fresh each time using only the files in the CD image, it means each time you have a new chance to do something new and test things without any fear of messing up your system.

    2. There is a way to install it to a hard disk and configure it to save changes. I will be explaining more about this in this chapter.

    Installing Software Temporarily

    Before trying to permanently install Tiny Core to a hard disk, it is important to understand the package manager that it uses. It is called tce-ab. You can run it by its name.

    tce-ab
    

    It has a lot of text with instructions that let you search for and install packages. For example, on my machine when I booted into Tiny Core on QEMU, I was able to search for and install the “nano” text editor and the “nasm” assembler.

    You can also directly install programs with the tce-load program. This is often faster than navigating the menus of tce-ab.

    tce-load -wi nano
    

    However, because even previously installed programs will be gone on the next reboot, it is time to teach you how to create a virtual hard disk and reboot into the emulator with a hard disk that we will install to.

    Installing to a Hard Disk

    First, exit the emulator and then use the qemu-img command below to create a 1 Gigabyte empty file that will be used as a hard disk.

    qemu-img create harddisk.img 1G
    
    qemu-system-x86_64 -drive file=Core-current.iso,media=cdrom -drive file=harddisk.img,format=raw,media=disk
    

    The Tiny Core install program is ironically not included in the cdrom file we are booting from. Therefore, it becomes necessary to install the installer!

    While you are booted into QEMU with both the cdrom and harddisk images, install the install script with the tce-load command below.

    tce-load -wi tc-install
    

    It will take some time to install the dependencies of the Tiny Core install script. Notable dependencies are Perl (a popular scriping language) and syslinux (the bootloader).

    After it finished installing, run this command:

    sudo tc-install.sh
    

    The installer asks a lot of questions about what options you want when you want to install.

    • i for installing from booted cdrom
    • f for frugal hard drive installation
    • 1 for whole disk installation
    • 2 for sda (first hard disk)
    • y for installing the bootloader
    • 3 for the ext4 file system

    Most other options you can leave blank and press enter.

    I know that process may have been a little complex but it highlights the difference between installing Linux and installing Windows.

    You don’t install Windows. It was already on your computer when you bought it. This means somebody else chose all the options for you.

    When you install Linux, you need to know some basic facts or at least google them when in doubt. This takes some time to learn but it gives you unrestricted control in the kind of system you are building for your software development.

    In fact Tiny Core provides a helpful book that explains some of these options.

    http://www.tinycorelinux.net/book.html

    The book covers the graphical interface which is available on a much larger ISO file. I chose to go the pure command line only route and adapt the instructions for the tc-install.sh script which only got a passing mention in the book.

    When you have completed those steps, it is now possible to boot directly into the hard disk without the cdrom!

    qemu-system-x86_64 -drive file=harddisk.img,format=raw,media=disk
    

    The main benefit of installing to a hard disk instead of just booting from the cd image each time is that any programs you install with tce-ab or tce-load will stay there and be available to use each time you reboot.

    Making a Persistent Home Directory

    However, the files in your home directory are deleted each time you reboot. However, there is an easy fix for this. We will open the bootloader configuration and add an option to restore the backup from sda1.

    First, open the config file:

    nano /mnt/sda1/tce/boot/extlinux/extlinux.conf
    

    And add this option to the line that starts with APPEND.

    home=sda1
    

    This means that the home directory will become an actual directory on the hard disk instead of a temporary location only loaded into RAM. With this step completed, you can begin programming in Assembly on your Tiny Core Linux system! Time to install the tools.

    NASM is already in the repository and this is the standard way to install it.

    tce-load -wi nasm
    

    However, FASM is not available in the repository but it can be easily downloaded from the official website. However, this system only has a terminal with no web browser. Don’t worry, there is a way! We can use the wget command that is already in Tiny Core Linux!

    wget http://flatassembler.net/fasm-1.73.35.tgz
    

    After the TGZ (Tar with GZip compression) file downloads, we need to extract the files from it.

    tar -xf fasm-1.73.35.tgz
    

    Now you can change to the fasm directory that was just created.

    cd fasm
    

    Inside are several files including “fasm” (the actual executable that can assembly all the programs in this book), “fasm.txt” the manual in plain text that describes both how to use FASM and also introduces the Intel instruction set. The “license.txt” may also be of interest.

    To install fasm, we should add it to somewhere where it can be in the current path. Check what the path is currently with this command.

    echo $PATH
    

    One of the directories that is in the path is “/home/tc/.local/bin”. This gives us the information we need to install fasm permanently there. Just copy fasm there like this:

    cp fasm ~/.local/bin
    

    Now enter “fasm” as a command and see what happens. If you see the following output, then it was done correctly!

    flat assembler  version 1.73.35
    usage: fasm <source> [output]
    optional settings:
     -m <limit>         set the limit in kilobytes for the available memory
     -p <limit>         set the maximum allowed number of passes
     -d <name>=<value>  define symbolic variable
     -s <file>          dump symbolic information for debugging
    
    

    This means that you can assembly and run any program that I have included in this book, Assembly Arithmetic Algorithms for Linux.

    Keep in mind however that programming in this terminal based environment may feel different because you have to use terminal text editors like vi,vim, or nano. These text editors are just as good as graphical ones except that there is no mouse support. However, I was hoping to give you the retro feeling of programming like a crazy person in the 1980s.

    This is just the tip of the iceberg about what Tiny Core Linux can do. However, I wanted to at least spend this chapter introducing this lesser known distro because it is small enough that it emulates with QEMU flawlessly.

    Although Debian, Ubuntu, Linux Mint, and many others are better than Tiny Core because they have more programs in their repositories, they are too large to emulate because their graphical X Windows System displays use a lot more memory and it is harder for a PC emulator like QEMU to emulate them properly.

    Consider Tiny Core Linux as a way to test the waters and get used to running commands in a Linux terminal before you are ready to install a more mainstream distro like Debian. However, once you have made the jump into the wonderful world of Linux, you will not be disappointed as a programmer because there is no shortage of text editors, assemblers, compilers, and even video games. For example, Final Fantasy 6 and Chrono Trigger from my Steam game collection both work on my Debian Linux system. Ironically, my Windows 11 laptop could not run Chrono Trigger.

    I wrote this chapter to do my small part in the world to help people discover the things I like about Linux and the freedom it offers.

    Tiny Core Linux makefile

    The following makefile is something I use to run commands for emulating Tiny Core Linux inside QEMU. I use it to remind myself what commands I use to set up a new installation of Tiny Core Linux.

    Core-harddisk:
    	qemu-system-x86_64 -drive file=harddisk.img,format=raw,media=disk
    Core-cdrom:
    	qemu-system-x86_64 -drive file=Core-current.iso,media=cdrom
    Core-cdrom-short:
    	qemu-system-x86_64 -cdrom Core-current.iso
    Core-cdrom_and_harddisk:
    	qemu-system-x86_64 -drive file=Core-current.iso,media=cdrom -drive file=harddisk.img,format=raw,media=disk
    harddisk:
    	qemu-img create harddisk.img 1G
    

    Of course, this chapter also serves as a reminder to myself about how to use Tiny Core Linux and also why it is one of my favorite distributions of Linux. I like it because sometimes I just want to have a text-only system upon which I can improve my scripting and command line usage skills. Modern Linux distros include Graphical User Interfaces where you can point and click your way to doing anything, but from the beginning it was not this way. Therefore, I always promote learning the Linux terminal because it is the one thing that stays consistent and trustworthy no matter which distro you are using at the time.

    I will admit that using the command line is a huge learning curve when you are first getting started. Perhaps I found it easier because I grew up with MS-DOS where text commands were all I had. In any case, knowing how to navigate directories on Linux to edit, copy, rename, and delete files is helpful because there are so many different graphical user interfaces and I can’t remember which menus to click on.

    But the real reason text commands are the best is because text can be copy pasted and then I am able to give you the exact commands to run so that you don’t have to spend months google searching for the right documentation on all these different things!

  • Assembly Arithmetic Algorithms RISC-V

    Assembly Arithmetic Algorithms

    RISC-V Edition

    Preface

    This book is the RISC-V edition of Assembly Arithmetic Algorithms. This is the third book in the series but it is a completely acceptable way to learn programming, even for beginners.

    The first book was for 16-bit DOS programming using Assembly. The second book was for 32-bit Linux programming using the same assembly language for Intel machines.

    But the book you are reading now, is fundamentally different in nature. It uses simulators that run in any operating system to teach a new type of Assembly language for the RISC-V (Reduced Instruction Set Computing-Generation 5) processor.

    RISC-V is important because it is a royalty free open standard. This means that as it catches on, more companies will be able to make cheaper computers because they will not have to pay royalties to the Intel or ARM companies. I guess you could say that it is Open Source Hardware, which in my opinion is the final piece we need to match the Open Source Software people like me already have been enjoying with GNU and Linux.

    Introduction

    First, let me introduce this book by telling you what I will teach you. By the end of this book, you will have enough information to write small programs that will run on your machine but also allow you to bypass complicated languages like C++, Java, or even the Bash Linux shell. Arguably, the beautiful thing about Assembly is its simplicity.

    RISC-V is great because it is a Reduced Instruction Set Computing device. It has fewer instructions to learn and remember, especially when compared to Intel. It also has more registers available for use. Each of them have special purposes and conventions for how they are used. However, as the programmer, you are allowed to break these conventions because right now, your focus should be on learning it for fun!

    Required Knowledge

    To get the most out of this book, some background on the Binary and Hexadecimal numeral systems is going to be helpful, but this is not strictly required because I will be providing functions you can use in your code that will convert between decimal (base ten), binary (base two), and hexadecimal (base sixteen).

    However, I would say that experience in at least one programming language is necessary for an understanding of terminology like “arrays”, “pointers”, “addresses”, “integers”, etc. I recommend the C Programming Language as a start. C++ is also a good starting language, but it tends to abstract details away that directly apply to Assembly Language, which is the lowest level a human can go for understanding a computer.

    But I think it is perfectly okay for this Assembly language to be your introductory language for the world of computer programming. The language is simple, beautiful, and in my opinion, was designed better than Intel x86. The makers of the RISC-V architecture saw what other processors were doing and in some ways tried to avoid making the same mistakes as previous generations did.

    RISC-V is a new processor type and philosophy that was created in 2010 at University of California, Berkeley. The V in its name is actually the Roman number 5. That means there were apparently those named I,II,III,VI in the past.

    Many people have high hopes about this new computer architecture that is also old enough to trust. Because it is 16 years old at this time and has been standardized, there are many simulators available. This book will present two of these simulators and perhaps a passing mention of others as I learn about them myself and can provide more links.

    But because RISC-V is still relatively young compared to Intel 8086 (year 1978) and ARM (year 1983), I expect that the timing of this book will be of use to people who have heard about RISC-V and wonder what it is about.

    Low Level

    Low level is a term that confuses people. People think something high-level is better than low-level. In simple terms, humans consider themselves superior to machines and therefore think themselves higher or more important because of their abstract thought.

    A computer thinks only in terms of numbers. A computer may not understand “high-level” abstractions such as love, religion, philosophy, etc, but that is not its job. A computer must add, subtract, multiply, and divide. These are the four arithmetic functions that many humans struggle with.

    Therefore, I ask you, between a human and a computer, who is really low level or high level? In the age of Artificial Intelligence taking over human jobs and beating humans at Chess, we would all do well to take this question seriously.

    I wrote this book because I think like a machine, and I hope to help others think this way because it is the best way to learn programming and control your computer by writing Assembly Language programs, or to go back to your favorite programming language with a greater understanding of why things work as they do.

    Why RISC-V

    After writing 3 programming books, I decided I wanted to learn a language that offered the things I love about C and Assembly but was also new and exciting at the time.

    I first learned RISC-V from Robert Winker’s book.

    https://leanpub.com/riscvassemblyprogramming

    It was also available on Leanpub and I thought his teaching style is a standard that I hope to live up to. Obviously he is more experienced and his book is probably better than mine. Even so, I wanted to do my own part to promote education about RISC-V because I want to see a world where programming is easier and computers are cheaper. As much as I love Intel machines because I grew up with them, RISC-V provided me a new learning experience that I hope others discover and enjoy as much as I have!

    Chapter 1: The First Program

    For this chapter, I will explain give the source code of an example program that works in both RARS and riscemu simulators. Take a good look at it and the comments I included. I will be explaining this in detail. I also recommend you type or copy and paste this code into a text editor and save the file as “main.s” in a place on your computer that you prefer.

    Hello World

    .data
    
    string0: .asciz "Hello World!\n"
    
    .text
    
    li a0, 1       # STDOUT file number
    la a1, string0 # address of string 
    li a2, 13      # length of string
    li a7, 64      # write call number
    ecall          # environment call
    
    li a0, 0       # status
    li a7, 93      # exit
    ecall          # environment call
    

    There are two sections named “.data” and “.text”. All variables used in the program should be defined in the .data section. The .text section is where your code starts executing. This organization scheme is required for most simulators and assemblers.

    This program prints “Hello World” followed by a newline. It uses only 3 kinds of instruction and is fairly easy to follow.

    • li = load integer (or immediate value)
    • la = load address (a special kind of integer)
    • ecall = enviroment call (or syscalls)

    The reason that sometimes li is used to load a register and other times la is used is because technically, there is a limit on the size of integers that can be part of an instruction. Instructions like “la” are technically macros for multiple instructions that load upper and lower bits of a register.

    But besides that, having la for memory addresses and li for regular numbers makes the code more readable in my opinion.

    ecall is the how you would call the system calls of your operating system. It is the same idea as “int 0x80” was in my Linux Intel Assembly book. However, in RISC-V, there are different registers and different system call numbers than you would expect on Intel CPUs.

    But more importantly, this program was written for simulators and not a real operating system. The call numbers, which are loaded into the a7 register, are specific to the RARS and riscemu simulators. In the next chapter, I will explain the differences between these two simulators and how to run the program.

    Chapter 2: Simulator Choices

    There are two simulators I personally use and test my code against. Both of them are Free Software and available to download from their Github repositories. I will offer some information about them so you can choose which to use when following along with this book.

    RARS

    RARS is a port of the MARS simulator for MIPS processors. It is written in Java and is downloadable as a

    https://github.com/rarsm/rars

    This book favors RARS because it is easy to use and is reliable enough to use from any operating system. It also supports a lot of system calls and is the simulator I learned to use first. Because it runs using Java, you must have the Java Runtime installed. However, since Java can be installed and run on any operating system, you can be sure that it will work no matter whether your host operating system is Windows, Linux, or Mac.

    On my system, I usually have the file named “rars.jar” in my home directory. This allows me to run my source file like this:

    java -jar ~/rars.jar main.s
    

    Because ~ is a shortcut for the home directory, this allows me to run it from whichever directory I happen to be in that contains my source file, which in this case is named “main.s”.

    riscemu

    Riscemu is a simulator written in Python. It does not have as many system calls built in but it is a good option for people who have Python installed but cannot, or don’t want to install Java.

    https://github.com/AntonLydike/riscemu

    Running a source file with riscemu is even easier that with RARS.

    riscemu main.s
    

    In my experience, riscemu also launches faster than RARS does, mostly just because RARS requires Java to load the whole virtual machine before it starts. Because riscemu is written in Python, and Python is written in C, it is only natural that it might be faster.

    However, riscemu is really picky about having a space after commas in your instructions. It will fail with cryptic error messages if you don’t have proper spacing between your arguments to an instruction. This is probably a bug but it allows for consistency in formatting if you just remember to add a space after each comma. If you don’t like to do this, just forget riscemu and stick with RARS.

    Why use a simulator?

    You might be wondering why I am recommending using these simulators rather than a real assembler for a real machine with an operating system. There are 3 reasons.

    • I don’t have a computer with a RISC-V processor.
    • Simulators can be used by more people because they don’t require buying new hardware.
    • No “risk” in trying out this new RISC based machine.

    In short, I use these simulators or emulators for the same reason I used DOSBox in the DOS version of Assembly Arithmetic Algorithms.

    An emulator allows people to learn the language a Central Processing Unit uses before they have invested time or money into learning it. This means no investment or sacrifice from you.

    In fact, you might decide to forget learning RISC-V Assembly and learn Java or Python instead. Even so, I wrote this book so that I can share what a beautiful language the RISC-V Assembly language is and why I enjoy coding in it.

    Chapter 3: System Calls

    There are many more system calls for RARS than I will be teaching in this book. riscemu has less than RARS but the table below shows the calls that these two simulators both have in common. The 3 calls are enough for most programs.

    System Calls for RARS and riscemu

    Name a7 a0 a1 a2
    exit 93 status
    read 63 fd buf count
    write 64 fd buf count

    For more advanced programs that open and close files, you will need to use different call numbers and also different mode numbers. Unlike Linux and the POSIX system calls, the simulators are meant for teaching the language but you can’t count on them being compatible with each other in the same way. It is pure luck that the system calls for the 3 calls above matched. It is precisely this reason that I chose RARS and riscemu as the simulators for this book.

    Registers on RISC-V

    There are a LOT more registers than there were on Intel machines. This makes using RISC-V very easy because you don’t have to use memory locations as often.

    Name meaning/usage
    zero always = zero
    ra return address
    a0->a7 arguments
    s0->s11 saved values
    t0->t6 temporary

    The zero register is just a register that always equals zero. It may seem weird but remember than RISC-V does not allow comparing a register directly with a number. Normally you need to load a number into another register. But because comparing with zero is a common operation, this zero register is available to be compared or copied any time!

    The ra register is important for function calls. It is the register that keeps where you will return to when the function is done. Because of this, you will run into trouble if you try to do something else with it.

    The other registers can technically be used any way you want except that those starting with ‘a’ are used for arguments to environment calls. For this reason, they are used more than others.

    The registers that begin with ‘s’ or ‘t’ are technically the same but it is a convention or tradition that t0 to t6 are used for temporary cases where you need to add, subtract, multiply, or divide numbers. After you are done with them, you use them for something else and forget what you did with them last time.

    The s0 to s11 registers are the most abundant and you are expected to keep things that endure most or all of the program in them. For example, you might keep a file descriptor in one of them so that you could copy it to the correct ‘a’ register when you need to.

    Because of the fact that you cannot compare or otherwise perform math on memory addresses directly, you have to always load everything into registers. However, because RISC-V has more registers, you can also write programs that run faster because you access memory less often.

    However, you will be loading and saving memory for variables stored in the data section. Usually these will be strings you are printing.

    In the next chapter I will be introducing a function that can print any string by automatically calculating its length. I will also be using the calling convention of the recommended register usage.

    To be continued

  • Chapter 10: A Teacher’s Burden

    Chad was concerned about what the young boy Simon had said to Luke regarding the flood in Genesis. Sure, he knew about the story, but when Luke told the children about God killing all the animals with a flood, something in him broke. How could he know what stories were true or not? He decided to focus more on the teachings of Jesus and began reading the Bible more and also doing other research.

    Meanwhile, Stacy had also become concerned. She took a break for several weeks and did not join Chad and Luke for the soccer and Bible stories because she felt like she had nothing to contribute and didn’t want to be around Luke because he was so rude to Chad. Oddly enough, Stacy met Chad at the library one day when they both went to look at children’s books.

    “Stacy! What brings you to the library?” asked Chad.

    “Oh, hi Chad. I wanted to find some books with Bible stories for children. I liked the way you explained the story of Daniel and his friends in a language they could understand.”, said Stacy.

    “That is sort of why I am here too. I need inspiration because I know a lot of stories, but some of them are not relatable to children or can traumatize them. I also haven’t seen your for awhile, are you okay?”, said Chad.

    “Yeah, I am okay…I guess. I just didn’t really want to be on the spot and have the responsibility of children looking up to me as an example when I am really not sure what I am doing with my life.”, said Stacy.

    “You know, it’s funny because I think the same thing about myself. Like, am I teaching these kids the truth about God or am I cherry picking the Bible verses I agree with and ignoring those I don’t? Maybe I am not cut out for teaching anything but soccer and board games. They have consistent rules I can follow, but am I really a good Christian?” said Chad.

    “What are you talking about, Chad? You are the best Christian in the town. None of us has all the answers, but you explained everything to Gabby when she interviewed you at the animal shelter. What you do for the animals, you are doing for Jesus.”, said Stacy.

    “Yeah, you’re probably right, but living for Jesus and teaching other people are two different things. Besides, Luke makes me doubt what is true about God.”, said Chad.

    “Did something happen with Luke?” asked Stacy.

    “Every week something happens with Luke. He tells the children Bible stories from the Old Testament, where God tells the Israelites to kill people in war. It all started when he told the flood story of Genesis 6 about God drowning all life on the planet except for those on the ark.”, said Chad.

    “Oh, I see. No wonder you seem so down. I am not so sure what to think about those stories either. They seem rather different than the teachings of Jesus. What are you going to do about soccer Sundays with the kids?” asked Stacy.

    "I was thinking of quitting. I don’t want to disappoint the kids, but I just can’t watch their faces as Luke tells them horror stories from the book that we are told is God’s word. I need some time to pray and think about it.

    “I understand completely, Chad. That is why I have been absent too. Just because I am a pastor’s daughter doesn’t mean I am a good Christian.”, said Stacy.

    “Nonsense, Stacy. You serve animals, and you haven’t been around humans the whole time I have known you to have possibly sinned anyway. You’re probably second in righteousness only to Jesus.”, said Chad.

    “Yeah, not quite. I also have a tattoo of a butterfly on my butt, and that is a violation of Leviticus 19:28.”, said Stacy.

    “Stacy, I am not here to judge!” said Chad

    “But do you still think I am a good Christian even though I have mutilated my butt and fallen short of the glory of God?”, said Stacy.

    “We have all sinned and fallen short of the glory of God, but I have to ask, why a butterfly?” asked Chad.

    “A butterfly starts as a caterpillar. Everyone expects it just to be what it was born as, but then it surprises everyone when it hides away for awhile and is then reborn as a new creature. It is like becoming a Christian by being born again.”, said Stacy.

    “I never really thought about it that way. I will remember that. So are you saying you committed an Old Testament as a sign that you became something new?” said Chad.

    "Exactly, Chad, 2 Corinthians 5:17 says:

    “Therefore, if any man be in Christ, he is a new creature: old things are passed away; behold, all things are become new.”

    So I believe that we should follow the new testament whenever there is a conflict between the old and the new. ", said Stacy.

    “Somehow, that makes a lot of sense. Thanks, Stacy. I think I know what I need to do about Luke and the kids.”

  • new program: chastdin

    I wrote another program which is actually a modification of chastack. This gets input from a user while it is running. Despite how simple it may seem, I had to work at reading from the keyboard because there are multiple ways to read a string from the user. I may add more to this program later, but it has all the important functions of a stack based calculator. Here is a screenshot that shows me using it. You can probably figure out what the commands do based on their name and the numbers printed. I have also attached the full assembly source code to this post.

    main.asm

    format ELF executable
    entry main
    
    include 'chastelib32.asm'
    include 'chastdin32.asm'
    
    main:
    
    mov dword[radix],10    ;I can choose the radix for integer output!
    mov dword[int_width],1 ;and the width of each integer for padded zeros
    
    mov ebp,chastack       ;mov the address of the beginning of the stack to ebp registers
    
    ;this program does not read command line arguments
    ;it always displays a message to tell user what the program does
    mov eax,string_help
    call putstring
    
    mov [last_char],0xA ;set newline as last_char so prompt will display
    
    main_loop:
    
    ;show the arrow indicating we wait for the user to enter something
    ;but only show it when the last character is a newline
    ;otherwise it will print too many if multiple commands were entered on the same line
    cmp [last_char],0xA
    jnz skip_prompt
    mov eax,string_prompt
    call putstring
    skip_prompt:
    
    call getstring ;get string and return address in eax
    
    ;we must restart the loop in case of an empty string
    ;if we didn't, strint would read the empty string and return 0
    ;then zero would be pushed to the stack, which is not what we want
    
    cmp dword[count],0 ;were there zero characters read?
    jz main_loop ;if yes, this was an empty string, retry input
    
    mov esi,eax    ;mov string to esi for string comparison
    
    ;Now we process the string the user entered
    ;First, we will try testing for commands
    ;If any of the predefined strings match the string in esi
    ;We jump to the label for that command
    
    mov edi,string_add
    call strcmp
    jz command_add
    
    mov edi,string_sub
    call strcmp
    jz command_sub
    
    mov edi,string_mul
    call strcmp
    jz command_mul
    
    mov edi,string_div
    call strcmp
    jz command_div
    
    mov edi,string_rem
    call strcmp
    jz command_rem
    
    mov edi,string_query
    call strcmp
    jz command_query
    
    mov edi,string_clear
    call strcmp
    jz command_clear
    
    mov edi,string_exit
    call strcmp
    jz command_exit
    
    ;The default command is to turn the argument into a number and push to stack
    command_num:
    
    mov eax,esi          ;mov the string to eax for processing numbers
    call strint          ;try to get a number from the string pointed to by eax
    cmp [strint_error],0 ;did we have zero errors in the strint function?
    jz num_push          ;if there were no errors, push this to stack
    
    mov eax,string_err
    call putstring
    mov eax,esi
    call putstring
    call putline
    jmp num_push_end ;skip the push because this can't be used
    
    num_push:        ;push the number to the fake stack
    add ebp,4
    mov [ebp],eax
    num_push_end:
    jmp main_loop
    
    ;These are the labels and code for each of the commands
    ;When a command is done, we jump back to the beginning of the loop
    
    command_add:
    mov eax,[ebp]
    mov dword[ebp],0
    sub ebp,4
    add [ebp],eax
    jmp main_loop
    
    command_sub:
    mov eax,[ebp]
    mov dword[ebp],0
    sub ebp,4
    sub [ebp],eax
    jmp main_loop
    
    command_mul:
    mov ebx,[ebp]
    mov dword[ebp],0
    sub ebp,4
    mov eax,[ebp]
    mov edx,0     ;zero edx before multiply
    mul ebx       ;multiply eax with value in ebx
    mov [ebp],eax
    jmp main_loop
    
    command_div:
    mov ebx,[ebp]
    mov dword[ebp],0
    sub ebp,4
    mov eax,[ebp]
    mov edx,0 ;zero edx before divide
    div ebx   ;divide eax with value in ebx
    mov [ebp],eax ;store quotient on stack
    jmp main_loop
    
    command_rem:
    mov ebx,[ebp]
    mov dword[ebp],0
    sub ebp,4
    mov eax,[ebp]
    mov edx,0 ;zero edx before divide
    div ebx   ;divide eax with value in ebx
    mov [ebp],edx ;store remainder on stack
    jmp main_loop
    
    command_query: ;print all numbers on the stack
    push ebp ;save value of ebp
    command_query_loop:
    cmp ebp,chastack ;is ebp equal to the address of stack start?
    jz command_query_end  ;if it is, end the putstack loop
    mov eax,[ebp]
    sub ebp,4
    call putint_and_line
    jmp command_query_loop
    command_query_end:
    pop ebp ;restore ebp to what it was before this command
    jmp main_loop
    
    command_clear: ;erase all numbers on the stack
    command_clear_loop:
    cmp ebp,chastack ;is ebp equal to the address of stack start?
    jz command_clear_end  ;if it is, end the putstack loop
    mov dword[ebp],0
    sub ebp,4
    jmp command_clear_loop
    command_clear_end:
    jmp main_loop
    
    command_exit: ;end the program
    
    main_loop_end:
    
    mov eax,1        ;exit (kernel opcode 1 on 32 bit systems)
    mov ebx,0        ;return 0 status on exit - 'No Errors'
    int 80h          ;system call for 32-bit Linux kernel
    
    argc dd 0
    
    string_err db 'Error: invalid number or command: ',0 ;Generic error message
    string_add db 'add',0
    string_sub db 'sub',0
    string_mul db 'mul',0
    string_div db 'div',0
    string_rem db 'rem',0
    string_exit db 'exit',0
    string_query db '?',0
    string_clear db 'clear',0
    
    string_prompt db '-> ',0
    
    string_help db 'chastdin is a stack based interactive calculator',0xA
                db 'Numbers are pushed on the stack and commands can do math.',0xA
                db 'It is a fork of chastack that reads from stdin instead of arguments.',0xA
                db 'Each line can contain multiple numbers or commands.',0xA
                db 'Math commands are add,sub,mul,div,rem',0xA
                db 'The exit command ends the program',0xA
                db 'The ? command prints the entire stack',0xA,0xA,0
    
    ;This program uses a virtual stack for convenience and portability
    ;I allocate memory for a virtual stack that we can index as if it was the real stack
    ;I name it "chastack" for Chastity's stack.
    
    db 6 dup 0 ;extra padding bytes
    chastack: rd 0x100
    

    chastdin32.asm

    ;Chastity's Standard Input header file
    ;The functions here are designed to read strings and numbers from standard input.
    
    ;getstring ;read characters from stdin until the first whitespace
    ;getline   ;read characters from stdin until the first newline,EOF,tab,etc.
    ;strcmp    ;compare two strings similar to the same function in C
    
    ;these variables are used as the default controllers
    ;for the getstring and getline functions
    ;buf stores keyboard input during those functions
    ;count stores how many bytes were read
    ;last_char stores the last character read
    ;usually this will be a space, tab, or newline
    
    buf db 0x100 dup '?'
    count dd 0
    last_char db 0
    
    ;summary
    ;the getstring function is the reverse function of putstring
    ;instead of printing a string to standard output
    ;it reads a string from standard input (AKA the keyboard)
    
    ;details
    ;the getstring function is designed to get a string of text
    ;which is terminated by whitespace or any non printable character
    ;the idea is that multiple strings can be passed on one line
    ;separated by spaces, similar to command line arguments
    ;this function was written for the specific purpose of converting any of
    ;my programs that used command line arguments to read from stdin instead
    
    getstring:
    
    mov [count],0 ;set count of characters read during this function to zero
    mov edx,1     ;number of bytes to read
    mov ecx,buf   ;address to store the bytes
    
    getstring_chars:
    
    mov ebx,0     ;read from stdin
    mov eax,3     ;invoke SYS_READ (kernel opcode 3)
    int 80h       ;call the kernel
    
    cmp eax,1     ;was 1 character read?
    jnz getstring_end ; if not, then end this loop
    
    mov al,[ecx]  ;mov last character read into al register
    
    ;check if this character is in the proper range to be part of the string
    
    cmp al,0x21      ;compare with 0x21 (!=exclamation)
    jb getstring_end ;jump if below to getstring_end label
    cmp al,0x7E      ;compare with 0x7E (tilde)
    ja getstring_end ;jump if above to getstring_end label
    
    ;if neither jump happened, keep the character and
    
    inc [count]   ;increment how many characters we have read
    inc ecx       ;increment address where next byte is read from
    jmp getstring_chars ;jump back to start of loop and keep reading
    
    getstring_end:
    
    mov [last_char],al ;save the last character read
    mov byte[ecx],0 ;terminate this string with a zero
    
    mov eax,buf ;mov the buffer address to eax for returning the string
    
    ret
    
    ;the getline function gets an entire line of text from the keyboard
    ;calling this function allows for a string that can contain spaces
    ;it considers as anything outside the range of 0x20 to 0x7E as the end of line character
    ;this is because the end of the line might be 0x0A on Linux
    ;or it might be 0x0D,0x0A on DOS or Windows.
    ;technically, it means tab will also terminate a line
    ;the intended use of this function is to read a filename
    ;filenames can contain spaces
    
    getline:
    
    mov [count],0 ;set count of characters read during this function to zero
    mov edx,1     ;number of bytes to read
    mov ecx,buf   ;address to store the bytes
    
    getline_chars:
    
    mov ebx,0     ;read from stdin
    mov eax,3     ;invoke SYS_READ (kernel opcode 3)
    int 80h       ;call the kernel
    
    cmp eax,1     ;was 1 character read?
    jnz getline_end ; if not, then end this loop
    
    mov al,[ecx]  ;mov last character read into al register
    
    ;check if this character is in the proper range to be part of the string
    
    cmp al,0x20    ;compare with 0x20 (space)
    jb getline_end ;jump if below to getstring_end label
    cmp al,0x7E    ;compare with 0x7E (tilde)
    ja getline_end ;jump if above to getstring_end label
    
    ;if neither jump happened, keep the character and
    
    inc [count]       ;increment how many characters we have read
    inc ecx           ;increment address where next byte is read from
    jmp getline_chars ;jump back to start of loop and keep reading
    
    getline_end:
    
    mov byte[ecx],0 ;terminate this string with a zero
    
    mov eax,buf ;mov the buffer address to eax for returning the string
    
    ret
    
    ;summary
    ;strcmp compares the string at esi to the one at edi
    ;eax returns 0 if the strings are the same and 1 if different
    ;the algorithm is simple but I will explain it for those who are confused
    
    ;details
    ;eax is initialized to zero
    ;a byte from each string is loaded into the al and bl registers
    ;the bytes are compared. if they are different, then we jump to the end
    ;However, if they are the same, then we check if one of them is zero
    ;for this purpose it doesn't matter whether we compare al or bl with zero
    ;because it is known that they are the same if the jnz did not take place
    ;if it is zero, this also jumps to the end of the function
    ;If neither jump took place, then we jump to the start of the loop
    ;but when the function finally ends bl will be subtracted from al
    ;this ensures that the function returns zero if the final characters are the same
    ;ebx,esi,and edi are preserved but eax is the return value
    ;also, the sub instruction at the end of the function also updates the flags
    ;so you can "jz" or "jnz" to a label after calling this function based on results
    
    strcmp:
    
    push ebx
    push esi
    push edi
    
    mov eax,0
    
    strcmp_start:
    
    ;read a byte from each string
    mov al,[edi]
    mov bl,[esi]
    cmp al,bl
    jnz strcmp_end
    
    cmp al,0
    jz strcmp_end
    
    inc edi
    inc esi
    
    jmp strcmp_start
    
    strcmp_end:
    sub al,bl
    
    pop edi
    pop esi
    pop ebx
    
    ret