OSDev.org

The Place to Start for Operating System Developers
It is currently Tue Apr 23, 2024 11:59 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 3 posts ] 
Author Message
 Post subject: [SOLVED] GCC 6.3.0 bug ?
PostPosted: Sun Apr 09, 2017 10:48 am 
Offline
Member
Member

Joined: Tue Feb 28, 2017 10:22 am
Posts: 25
Hello guys,
I just wanna share something with you that I discovered during my keyboard driver's debug phase.

Here is my function to write a byte to the keyboard :

Code:
void Keyboard_writeByte(uint8_t value) {
   while(Keyboard_waitingForAck) {
      hlt;
   }

   Keyboard_waitingForAck = true;
   Keyboard_lastCommand = value;

   PS2_data_write(Keyboard_port, value);
}


In assembly, it gives this (as seen by IDA Pro) :

Code:
.text:08000000 ; void __cdecl Keyboard_writeByte(uint8_t value)
.text:08000000                 public Keyboard_writeByte
.text:08000000 Keyboard_writeByte proc near            ; CODE XREF: Keyboard_init+11p
.text:08000000                                         ; Keyboard_init+1Dp ...
.text:08000000
.text:08000000 value           = dword ptr  4
.text:08000000
.text:08000000                 sub     esp, 0Ch
.text:08000003                 cmp     ds:Keyboard_waitingForAck, 0
.text:0800000A                 mov     eax, [esp+0Ch+value]
.text:0800000E                 jz      short loc_8000013
.text:08000010
.text:08000010 loc_8000010:                            ; CODE XREF: Keyboard_writeByte+11j
.text:08000010                 hlt
.text:08000011 ; ---------------------------------------------------------------------------
.text:08000011                 jmp     short loc_8000010
.text:08000013 ; ---------------------------------------------------------------------------
.text:08000013
.text:08000013 loc_8000013:                            ; CODE XREF: Keyboard_writeByte+Ej
.text:08000013                 sub     esp, 8
.text:08000016                 mov     ds:Keyboard_lastCommand, al
.text:0800001B                 movzx   eax, al
.text:0800001E                 push    eax
.text:0800001F                 push    ds:Keyboard_port
.text:08000025                 mov     ds:Keyboard_waitingForAck, 1
.text:0800002C                 call    PS2_data_write
.text:08000031                 add     esp, 1Ch
.text:08000034                 retn
.text:08000034 Keyboard_writeByte endp


My keyboard ISR sets Keyboard_waitingForAck to false when the keyboard sends an ACK.

But as you can see in the assembly code, it is never going to check if Keyboard_waitingForAck's value has changed, even if in the C code, the while loop should exit if Keyboard_waitingForAck is false.

So I decided to change my C code :
Code:
void Keyboard_writeByte(uint8_t value) {
   while(Keyboard_waitingForAck) {
      Console_write("\0");
      hlt;
   }

   Keyboard_waitingForAck = true;
   Keyboard_lastCommand = value;

   PS2_data_write(Keyboard_port, value);
}


In assembly, it gives that :
Code:
.text:08000000 ; void __cdecl Keyboard_writeByte(uint8_t value)
.text:08000000                 public Keyboard_writeByte
.text:08000000 Keyboard_writeByte proc near            ; CODE XREF: Keyboard_init+11p
.text:08000000                                         ; Keyboard_init+1Dp ...
.text:08000000
.text:08000000 value           = dword ptr  4
.text:08000000
.text:08000000                 push    ebx
.text:08000001                 sub     esp, 8
.text:08000004                 cmp     ds:Keyboard_waitingForAck, 0
.text:0800000B                 mov     ebx, [esp+0Ch+value]
.text:0800000F                 jz      short loc_800003A
.text:08000011                 jmp     short loc_8000020
.text:08000011 ; ---------------------------------------------------------------------------
.text:08000013                 align 10h
.text:08000020
.text:08000020 loc_8000020:                            ; CODE XREF: Keyboard_writeByte+11j
.text:08000020                                         ; Keyboard_writeByte+38j
.text:08000020                 sub     esp, 0Ch
.text:08000023                 push    offset unk_80001A0
.text:08000028                 call    Console_write
.text:0800002D                 hlt
.text:0800002E ; ---------------------------------------------------------------------------
.text:0800002E                 add     esp, 10h
.text:08000031                 cmp     ds:Keyboard_waitingForAck, 0
.text:08000038                 jnz     short loc_8000020
.text:0800003A
.text:0800003A loc_800003A:                            ; CODE XREF: Keyboard_writeByte+Fj
.text:0800003A                 sub     esp, 8
.text:0800003D                 mov     ds:Keyboard_lastCommand, bl
.text:08000043                 movzx   ebx, bl
.text:08000046                 push    ebx
.text:08000047                 push    ds:Keyboard_port
.text:0800004D                 mov     ds:Keyboard_waitingForAck, 1
.text:08000054                 call    PS2_data_write
.text:08000059                 add     esp, 10h
.text:0800005C                 add     esp, 8
.text:0800005F                 pop     ebx
.text:08000060                 retn
.text:08000060 Keyboard_writeByte endp


The call to Console_write() does absolutely nothing, but as GCC does not know what it can do, it checks for Keyboard_waitingForAck because Console_write() could have changed its value (logical).

And guess what, it works !

Do you guys have an idea why GCC is doing this and how I can fix it ?

PS : My compile line is
Code:
i686-elf-gcc -Wall -Wextra -O2 -ffreestanding -nostdlib -g -c -std=gnu99 $< -o $@

And my linking line is
Code:
i686-elf-gcc -T linker.ld -Wall -Wextra -O2 -ffreestanding -lgcc -nostdlib -g


Last edited by Ankeraout on Sun Apr 09, 2017 11:12 am, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: GCC 6.3.0 bug ?
PostPosted: Sun Apr 09, 2017 11:06 am 
Offline
Member
Member

Joined: Mon Jan 03, 2011 6:58 pm
Posts: 283
Is "Keyboard_waitingForAck" declared as volatile?

- Monk


Top
 Profile  
 
 Post subject: Re: GCC 6.3.0 bug ?
PostPosted: Sun Apr 09, 2017 11:08 am 
Offline
Member
Member

Joined: Tue Feb 28, 2017 10:22 am
Posts: 25
No, it was declared immediately after the #include instructions, as global variable.
Code:
bool Keyboard_waitingForAck = false;


(Thanks btw, now I know what volatile is)


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 3 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot], DotBot [Bot], ebeneEinHalb, Google [Bot], Majestic-12 [Bot] and 105 guests


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 post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group