flat assembler
Message board for the users of flat assembler.

Index > OS Construction > Segment Register Causing Interrupts to Hang [Solved]

Author
Thread Post new topic Reply to topic
XtremeDude47



Joined: 14 Dec 2011
Posts: 2
XtremeDude47
Hi,

I'm currently adding FAT12 write support into my OS, however I've ran into an odd problem where if I call one of my own interrupts, the system just hangs, as if it just completely stops, only that the cursor is still blinking.

The code below is from my FAT12 read function, which works fine. This code simply capitalises all of the letters in the FAT12 name:

Code:
;Note-DI:SI points to the filename
mov cx, 0x000B

ReadCapitalizeFileNameLoop:

cmp BYTE [DS:SI], 'a'
jb ReadFileNameLetterIsAlreadyCapital

sub BYTE [DS:SI], 0x20      ; -32 to make it a capital letter

ReadFileNameLetterIsAlreadyCapital:

inc si     ; increment SI to capitalise the next character

loop ReadCapitalizeFileNameLoop    


I decided to recycle this code for the write function, although I had to use FS instead of DS for the segment because I'm storing other information in DS in the write function:

Code:
;Note-DI:SI points to the filename 
mov cx, 0x000B

WriteCapitalizeFileNameLoop:

cmp BYTE [FS:SI], 'a'
jb WriteFileNameLetterIsAlreadyCapital

sub BYTE [FS:SI], 0x20        ; -32 to make it a capital letter

WriteFileNameLetterIsAlreadyCapital:

inc si     ; increment SI to capitalise the next character

loop WriteCapitalizeFileNameLoop    


Now for some reason, using FS or even GS causes my OS to hang if I call one of my own interrupts. I've confirmed that all values are as they should be, so i'm sure thats not what's causing this.

I have found that this code doesn't make interrups hang if I take out either the subtraction OR the comparison, but not if both are present. Also I found that when both are present, the comparison assembles to:

Code:
64 80 3D 61 72 06    


And the subtraction assembles to:

Code:
64 80 2D 20 47 E2 F1    


However, when only the comparison is present, it assembles to:

Code:
64 80 3D 61 72 02    


And when only the subtraction is present, it assembles to:

Code:
64 80 2D 20 47 E2 F7    


Notice that the last byte of both comparisons are different, and the last byte of both subtractions are different. So what I did was I included both the comparison and the subtraction at once, which causes interrupts to hang. However, this time I changed the last byte of the comparison (0x06) to the last byte of the comparison that is assembled with no subtraction present (0x02), and this solved the problem! Now my question is, why does this code cause my interrupts to hang if I call them when I use FS or GS in the above code? I just don't see the relation, and although there are many workarounds I can think of off the top of my head, I would still really like to know why this happens.

Thanks for any replies! Smile


Last edited by XtremeDude47 on 10 Oct 2012, 12:18; edited 1 time in total
Post 09 Oct 2012, 17:36
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17624
Location: In your JS exploiting you and your system
revolution
Those codes change because you are looking at the next instruction jb/loop:
Code:
cmp BYTE [FS:SI], 'a' ;64 80 3D 61
jb WriteFileNameLetterIsAlreadyCapital ;72 06
sub BYTE [FS:SI], 0x20; 64 80 2D 20
inc si ;47
loop WriteCapitalizeFileNameLoop ;E2 F1    
If you delete an instruction then the jb/loop offsets will change to reflect the shorter distance needed to jump.

We can't help you with the small section of code you have posted. Perhaps you can give a minimal compilable example showing your problem.
Post 10 Oct 2012, 01:11
View user's profile Send private message Visit poster's website Reply with quote
XtremeDude47



Joined: 14 Dec 2011
Posts: 2
XtremeDude47
Of course! I hadn't realised that I had included the jb and loop instructions! Although in retrospect, I should have figured that something wasn't quite right with the 6/7 byte instructions! Razz

Anyhow, I've been playing around with the code a bit, and I've discovered that its not the segment register which causes this problem, but rather the segment that the segment register points to. I'm still not sure why this is happening, though, as I've been pointing my segment registers to that same segment without any problems up until now. I would give a minimal compilable example, however I've been unable to reproduce the problem independantly, so theoretically, the actual code is fine, but there is a problem with that code when implemented into the kernel. Confused

I understand that not much can be done with that small snippet of code I've provided, however its the best I can provide without the whole Kernel source, which is huge, messy and is 98% irrelevant code - but its the only place where the problem can be reproduced at this point. I'll check the code again and provide the kernel along with anything else I find is relevant.


EDIT:

I found the cause of the problem! Very Happy Before all this, in my read function I used the unpadded file name length as a counter to capitalise the filename before it was padded, I then copied that same code to my write function, which capitalises the filename after its padded. I knew that after the filename was padded it would always be 11 bytes long, so I removed:

Code:
mov cx, WORD[FS:UnpaddedFileNameLength]   ; I also just realised that I forgot to correct this for the first snippet in my first post    


from the beginning of the code, and in a moment of stupidity, I somehow forgot to replace it with:

Code:
mov cx, 0x000B    


When I posted the code earlier, I noticed that this was missing, however I thought that I simply didn't select that line while copy-pasting, so I put it in the code in my first post, but not in my actual code! Consequently, because of some large, arbitrary CX value from previous compuatations, my function kept modifying bytes past the filename, and eventually overwrote my interrupts in memory! (because the kernel data area is 'before' the ISR area) Very Happy The specific erroneous segment that I mentioned earlier causes interrupts to hang because that is both my kernel's data and code segment, hence, by using a different segment, the ISR's weren't being overwritten!

Anyhow, here is the working code if anyone wants it:

Code:
;Note-DI:SI points to the filename  
;mov cx, WORD[FS:UnpaddedFileNameLength]   ; CX value used for this loop in the FAT12 read function
mov cx, 0x000B     ; I forgot to add this in my kernel!

WriteCapitalizeFileNameLoop: 

cmp BYTE [FS:SI], 'a' 
jb WriteFileNameLetterIsAlreadyCapital 

sub BYTE [FS:SI], 0x20      ; -32 to make it a capital letter 

WriteFileNameLetterIsAlreadyCapital: 

inc si     ; increment SI to capitalise the next character 

loop WriteCapitalizeFileNameLoop    


Thanks revolution! Very Happy
Post 10 Oct 2012, 11:31
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.

Website powered by rwasa.