2023-11-05 - In IL: Field Definitions
Fields are used to store information as part of a type.
.field <attributes…> <type> <Id> <initializer>
A field is declared using the .field directive. This is followed by a set of attributes which describe how the field behaves. The type indicates what kind of data the field contains, Id is the name of the field, and the initializer is used to set the value of the field
There are a variety of attributes that can be set.
Accessibility
The accessibility attributes are used to indicate where the field can be accessed.
Attribute | Description |
---|---|
private | Visible only within the containing class |
famandassem | Visible to containing class and derived classes within the same assembly |
assembly | Visible to the containing assembly |
family | Visibility to containing class and derived classes |
famorassem | Visibility to containing class and derived classes or to the containing assembly |
public | Visible everywhere |
Contract Attributes
The contract attributes are used to control how the field can be used
Attribute | Description |
---|---|
static | Indicates that the field is associated with the type. Not specifying static means that the field is specific to each instance |
initonly | Indicates that the field can only be modified in a constructor |
literal | (static only) indicates that the field can only have the value specified as part of its declaration |
Interoperation Attributes
The marshal (<NativeType>) attribute is used to specify how this field should be handled during marshalling
Special attributes
These attributes are used to indicate that the field should be treated in a special way
Attribute | Description |
---|---|
rtspecialname | The field has a special meaning to the runtime |
specialname | The field has a special meaning to something besides the runtime |
Type
We saw examples of types when we looked at variables. User defined value types start with valuetype and reference types start with class. This is followed by the fully qualified name of the type including namespaces and the source assembly. Built-in types use the simple name of the type and value or reference type is implied.
Initialization
initialization is specified using an equal sign followed by <type>(<value>) where type is one of the built-in types and value is the value to initialize the variable with.
Next time we will look at some examples.
2023-09-03 - DataTypes: Binary Arithmetic
Last time I said we would talk about negative numbers next but I realized I should probably explain binary arithmetic first. It's easier to show negative numbers working if you understand how binary math with positive numbers works. So that's what we are going to do today.
Binary arithmetic is actually easy. It mostly works the same as decimal arithmetic except we only have two digits instead of ten.
Lets start with a simple addition example, 8 + 3. In binary that's 1000 + 11. We setup the equation as we would normally and just go through the steps of adding each digit together in turn.
We start on the right hand side and get 0 + 1 = 1. Fairly basic math. This is the same for the second digit as well. Then we have a 0 which just drops down and the 1 does the same. This gives us 1011 which is 11 in decimal. 8 + 3 = 11 and 1000 + 11 = 1011.
Now let's look at something a bit more complicated, 15 + 25. In binary that would be 1111 + 11001.
Again we start on the right hand side. 1 + 1 = 10 (2) which means the result is 0 and we have a carry of 1. Carries work the same as they do in decimal math, they simply get added to the next digit. The next two digits are the same due to the carry being included in the addition. The fourth digit is 1 + 1 + 1 with the third 1 being the carry. 1 + 1 + 1 = 11 (3) so the result is 1 with a carry of 1. We then again have 1 + 1 = 10 and that gets added to the result which is 101000 or 40 in decimal.
As you can see the combination of digits is very limited. 0 + 0 = 0, 0 + 1 = 1, 1 + 0 = 1, 1 + 1 = 10. The most complicated calculation to do is 1 + 1 + 1 = 11 if both digits are 1 and we have a carry.
Now let's look at subtraction with 19 – 3.
We start with 1 – 1 = 0. This is the same for the second digit as well. Then we have 0 – 0 = 0, 0 – 0 = 0 and 1 – 0 = 1. This gives us 10000 or 16.
Now let's look at 20 – 3. That would be 10100 - 11
We again start with the right and do 0 – 1 which can't be done so we borrow from the next digit but the next digit is also 0 so it also needs to do a borrow. The third digit in the top number is a 1 so it can be used for borrow and becomes 0. Then working back the second digit becomes a 10 because of the borrow but we need to borrow from it so it becomes a 1 because 10 – 1 = 1. Now we have a 10 for the first digit and we can finally subtract the 1 so we do 10 – 1 = 1 again. For the next digit we have 1 – 1 = 0 and the rest of the digits just drop down to give us 10001 or 17.
Multiplication works like you would expect. Let's look at 26 x 3 which would be 11010 x 11.
With decimal multiplication you multiply the top number by each digit in the bottom number and then sum the results. Each intermediate result has one more 0 than the previous one. This is because each digit is 10 (or 2 for binary numbers) times bigger than the last. Binary multiplication works the same way. You start with the right most digit and multiply the top number by that. In this case the digit is a 1 so we just write down the top number as our first intermediate result. The second digit is also a 1 but we're in the 2's position now so we write down the top number with an extra 0 as our second intermediate result. This is effectively 26 + 26 x 2. Adding the two numbers we get 1001110 which is 78 or 26 x 3. Because binary only has two digits it's easy to come up with the intermediate values. They are either 0 because the digit is a 0 or the number shifted over a number of times because the digit is a 1. You can end up with a lot of additions to do if you have large numbers but the process is simple.
Division is similar. The number either fits and you put a 1 in the result or it doesn't and you put a 0. For example let's look at 30 (11110) divided by 8 (1000).
Like with decimal long division we consider more and more digits of the dividend until the divisor fits into it. Unlike decimal division we don't have to worry about knowing the multiples of the divisor. It either fits and the result gets a 1 or it doesn't and it gets a 0. After moving over three times we get 1111 which is bigger than 1000. So we subtract 1000 from 1111 to get 111 and then pull down the 0 from the dividend to get 1110. We then use this value and repeat the process. 1110 is greater than 1000 so we put another 1 in the result and take the difference. Pulling down another 0 we get 1100. Do it again and we get 1000. Once more and we get 0. Just as with decimal division the decimal point in the dividend and the quotient is the same. This gives us a result of 11.11. We'll look at fractional numbers later but for now just believe me when I tell you this is 3.75, the result of dividing 30 by 8.
Notice that we basically just shifted 11110 over 3 digits to get 11.11. This is because we divided by 8 which is a power of 2. This is the same as dividing a decimal number by powers of 10.
Note that computers don't actually do math step-by-step like this. They either use algorithms to speed up the process or have logic implemented in circuits which can determine the result electronically. For example the result of adding two digits (A and B) and a carry (C) is (A XOR B) XOR C. The result is 1 if either of the inputs are 1 unless the carry is also 1. The carry out logic is a bit more complicated but can still be implemented with simple logic gates.
It's also important to remember that computers mainly work on numbers with a fixed number of digits. This means that if a numbers get to big it ends up wrapping around because there's no more digits for it to grow into. Earlier we looked at 1111 + 11001 and got 101000 but if the this was a 5-bit computer the result would actually be 01000. That's because the largest value that can be stored in 5 bits is 31. The math is the same but the carry out from the final 1 + 1 is lost.
Computers actually use this as a trick to implement negative numbers as we will see next time when we look at how computers implement negative numbers. I promise will will actually do it this time.
2023-02-05 - Perspectives
A while ago I was walking down the street when I saw a hotel employee carrying the luggage of a fancy looking couple into a hotel. This started me thinking about how different some people's lives are. Having someone carrying their luggage probably feels normal for them but I would find it weird. "I can do that, you don't need to do that". Maybe they do find it weird. Maybe they only recently came into money or this is a special trip to commemorate their anniversary or they just find it weird even though it's how things have always been for them.
I've also been thinking about this in regards to pastimes. I look at people who play instruments or cook amazing meals and wish I could do that. There's no reason I can't except that I have my spare time ear marked for other things. Writing stuff like this, learning about computers, working on programming projects. Those other people aren't doing those things which is why they can cook and play music. I can't not program though just as they can't not cook or play instruments. Different people have different things that interest and excite them.
I enjoy my life. I think I had a pretty good childhood. I think I have good opinions about things. I think I'm productive in my free time. But I also think a lot of people would look at my life and go "huh?". I would probably do the same about their lives. The human experience is so varied that it's almost unnerving to think about. The number of people living entirely different lives. With different opinions, thoughts and priorities. There's people who can waste a billion dollars without blinking and there are people who would do anything for 5 cents.
It's difficult to understand people when you only see them through your own perspective. Through your own experiences. They don't share those experiences or perspectives so it's very unlikely that they will make sense in that context. To make sense of people you have to shift into their perspective, think about what they've experienced.
People are complicated.
2023-01-02 - 2023
I am hoping that 2023 will be less stressful and more productive. Hopefully that statement won't draw the wrath of the universe.
Lupo
The priority for Lupo this year will be finding food that agrees with his stomach better. I also need to do some tests with food bowls to fine arrangements that work best.
House
In February I'm hoping that my financial situation will be calm enough that I can get my other two Desert Bus posters framed. Then I can put all of them up.
In March I need to look into getting a new furnace. Mine is thankfully still working but it's starting to act a little strange and is over 40 years old. I doubt a new one will last that long.
After that I need to see how my financial situation is looking and see about buying some new chairs.
Volunteering
I really need to find some kind of volunteer opportunity this year. At the very least I need 10 volunteer hours by may to claim as my Professional Development Hours for APEGA but I would also like to find somewhere that I can go routinely and really get involved with.
I can't spend all my time with the cats.
Sickness
I hope to get sick less
Mafia Story Comparison
I would really like to get this series done this year. There's a lot of things that I want to show people and I'd like to do it while I remember them.
Breadboard Computer Project
I've ordered the replacement ROMs and a Zero-insertion force socket which will hopefully work better than the other sockets I got. After that I need to connect up the switches and then I can start working on my own program ideas.
I also want to document the 6502 instruction set.
Scanning
After I got the breadboard computer finished and moved off of my kitchen table I can start getting back into scanning. I want to scan The front and back of each album in my CD collection. I also need to go through my set of photographs to see which ones I don't already have a scan of. Then I can work on filling out my photo album.
I also want to get a book scanner but that'll be expensive so it'll depend on how the house stuff go.
Boxed Software Collecting
I hope to spend significantly less money on boxed software this year. My plan is to put $100 into my PayPal account each month and that'll determine how much money I can spend. If I buy a lot of little things then I can't buy a big thing but if I don't spend a lot and save up then I might be able to.
There are a few things I would like. I've seen some interesting boxes for Windows 1.0 and I'd like a retail copy of DOS 3. I'd also like a copy of Word for Windows 2.0. OS/2 1.30.2, Warp 3, Warp 4.5 and a software development program.
My main goal for this year is to install and use all of the software I already have. That means I need to get a working 5.25 inch floppy drive and a setup to use it so that I can image the disks that I don't have a 3.5 inch version of.
Computer History Tour
The next stop on the history tour is Altair Basic. I have a paper tape and a caseate version for my Altair 8800 clone. I want to work through the manuals for those two versions and write up a reference for each of them.
Next I want to do a little bit of an investigation into the assembly development system for the Altair and then look into CP/M. Then I can write a reference for CP/M.
As an offshoot of this I also want to write a decompiler. This will start with support for 8080 instructions and CP/M executables but I hope to expand it to other systems.
This will likely also lead to the first in a series of posts looking at different executable formats.
Disk Structure Investigation
The next step for this project is finishing up the assembly program to make images of hard disks. Then I need to review the way the Disk Viewer application reads files. Currently it tries to load everything at once which is fine for 2 MB floppies but doesn't work well for 2 GB hard disks. My plan is to write an abstraction layer between the underlying image format and the disk structure model. The data from the image will get loaded on-demand as the model requests it.
My priority will be decoding the MBR so that I can hopefully get my OS/2 partition to boot. Next will be figuring out how to identify which bits of data are available in the BPB and then navigating the file system. The file system part is mainly where the on-demand loading comes into play.
Exercises and Posts
Along with everything else I also want to get back into the routine of working through chapters in my programming books and writing posts.