Hi,
HardCoder wrote:I'm Having a rather weird problem. Every Time I try to make a call To "NewLine" (Extern) which is declared in another file , the Call Works but when i try to Ret from the procedure . It Just Triple Faults.
The reason for the exception could be many things (including bad values for SS:ESP, bad paging setup, bad segments/GDT, etc); and the reason for the exception may just be a symptom of bugs elsewhere (e.g. boot loader that messes up the code, memory manager that thinks ROM is RAM or allows the same RAM to be allocated twice, scheduler that trashes something, etc).
The first step would be to get some information about the problem. For example, run it in something like Bochs and see what type of exception leads to the triple fault (e.g. page fault or general protection fault), and which values are in which registers at that time. Bochs will put all this in its log, so you don't even need to use the inbuilt debugger for that. If that's not enough information, something like the inbuilt debugger in Bochs can be a powerful tool (it lets you examine contents of registers, memory, etc while seeing the effects of every instruction leading up to the exception).
Code: Select all
NewLine:
Mov Ax , [Cursor]
Shl Al , 1
Shr Al , 1
Mov Dh , 0
Mov Dl , Al ;DX = low 7 bits from [Cursor], with all other bits cleared
Mov Ax , 80
Sub Ax , Dx ;AX = 80 - (low 7 bits from [Cursor])
Mov Dx , [Cursor]
Add Dx , Ax ;DX = "[Cursor]" + 80 - (low 7 bits from [Cursor])
Mov [Cursor] , Dx ;"[Cursor]" = "[Cursor]" + 80 - (low 7 bits from [Cursor])
add Ebx , 2 ;EBX = unknown + 2
mov ah , "H"
Mov [ Gs:Ebx ] , Ah ;[unknown + 2] = 'H'
Ret ; HERE IS THE PROBLEM
Are you sure this code does anything you intended?
My guess is that "[Cursor]" is meant to contain the character number for the cursor's position (e.g. where the value 123 is column 43 on row 1), and that the calculation for the new cursor position is wrong. I'd also assume that you forgot to do something like "movzx ebx,[Cursor]" before the "Mov [ Gs:Ebx ], Ah" instruction, and that the "Mov [ Gs:Ebx ], Ah" instruction should have been "Mov byte [Gs:Ebx * 2], 'H'" (where the GS segment register contains the base address of display memory).
If "[Cursor]" is meant to contain the character number for the cursor's position, then you'd need to do the equivelent of "value = value - value % 80 + 80". The only sane way to do that is with the DIV instruction (e.g. divide by 80 to find the remainder, then subtract the remainder from the original value and add 80). It's almost like you've got hexadecimal and decimal confused. The actual calculation you're doing is "value = value + 80 - (value & 0x7F)", which would've been a valid optimisation for "value = value - value % 0x80 + 80" (but 0x80 is not 80).
Then there's efficiency. For example, your broken code could've been done with half the instructions (assuming none of the registers are used for returned values) - for example:
Code: Select all
NewLine:
mov dx,[Cursor] ;dx = [Cursor]
mov ax,80 ;ax = 80
and dx,0x007F ;dx = low 7 bits from [Cursor]
sub ax,dx ;ax = 80 - (low 7 bits from [Cursor])
add [Cursor], ax ;[Cursor] = [Cursor] + 80 - (low 7 bits from [Cursor])
mov byte [gs:ebx+2],'H' ;[unknown + 2] = 'H'
ret
Anyway, based on a large number of assumptions (caused by inadequate commenting in the original), I'm guessing the code should be something like:
Code: Select all
NewLine:
movzx eax,word [Cursor] ;eax = [Cursor]
xor edx,edx ;edx:eax = [Cursor]
mov ebx,80 ;ebx = 80
div ebx ;eax = [Cursor] / 80, edx = [Cursor] % 80
sub ebx,edx ;ebx = 80 - [Cursor] % 80
add bx,[Cursor] ;ebx = [Cursor] - [Cursor] % 80 + 80
mov [Cursor],bx ;[Cursor] = [Cursor] - [Cursor] % 80 + 80
mov byte [gs:ebx*2],'H' ;Put a "H' where the new cursor is
ret
Cheers,
Brendan