-1

I am trying to programm a bootloader and therefore i use inline assembly. but i have struggles using diffrent methods for diffrent assembly code. I wrote the following as function:

char readInput(){
   char i = 'a';
   asm(
      "mov $0, %%ah;"   //parameter for read char
      "int $0x16;"      //interrupt for read
      "mov %%al, %0;"   //put readen char in variable i
       :"=r" (i)        //random register which is free for i
       :: "ax"          //was used
    );
   return i;
}

when i call it like 3 times in my main-function f.e.:


readInput();
readInput();
readInput();

and I execute it and press 1x 'd' he reads instant 3x 'd' :( i have no idea why. Does anyone know?

PROBLEM IS SOLVED! Correct code to read input:

char readInput(){
   char i = 'a';
   asm(
      "mov $0, %%ah;"   //parameter for read char
      "int $0x16;"      //interrupt for read
      "mov %%al, %0;"   //put readen char in variable i
       :"=r" (i)        //random register which is free for i
       :: "ax"          //was used
    );

   asm("");
   return i;
}
Ett
  • 1
  • 2
  • `&&ah`? Does that even assemble? If so, it's not to the register name `%ah`. Check with a disassembler. Also, what toolchain are you using to build 16-bit code? – Peter Cordes May 10 '22 at 16:49
  • 3
    Why would it wait? `int 0x16` is reading the scancode of the key pressed down. That's all. https://en.wikipedia.org/wiki/INT_16H – Eugene Sh. May 10 '22 at 16:49
  • yea thats also what i want, but when i call the function a second time it reads the same char from before without pressing a new character on my keyboard :c – Ett May 10 '22 at 16:54
  • Because you are calling them too fast. It is reading the same keystroke. – Eugene Sh. May 10 '22 at 16:55
  • 1
    and as in en.wikipedia.org/wiki/INT_16H specified, it is "ah" where i have to specify what i want to do with 0x16 and i am using qemu-system-x86_64 if u mean this – Ett May 10 '22 at 16:55
  • ah okay i guess its that, but how can i let it calm down? When i would copy that code and write it 2x it would wait for a 2. keypress – Ett May 10 '22 at 16:56
  • You can loop after the key press until you detect it is de-pressed, for example. Or record the current scan code, and only check if it changed. – Eugene Sh. May 10 '22 at 16:59
  • 2
    @EugeneSh.: I thought INT 16h / AH=00h was supposed to wait for a keystroke if the buffer is empty. It seems to me more likely that `mov $0, &&ah;` doesn't actually zero out AH because of the weird `&&`. – Nate Eldredge May 10 '22 at 17:17
  • Yeah, I can't get your code to build at all with gcc or clang; the empty character `''` is invalid, and `&&ah` barfs as well. What on earth are you using to compile this? Or is this not your actual code (e.g. you retyped it from memory instead of pasting the code you are actually using)? – Nate Eldredge May 10 '22 at 17:18
  • @NateEldredge I could be wrong, used this like 25 years ago in practice, but now just read the description – Eugene Sh. May 10 '22 at 17:22
  • no i rly need to use %%ah because i am using inline assembly in C – Ett May 10 '22 at 17:22
  • Yes, `%%ah` would be right. But your code has `&&`. Please check carefully that the code in your question is actually the code you are using. – Nate Eldredge May 10 '22 at 17:23
  • 1
    How did you even compile this with typos in it? An actual [mcve] should be a copy/paste of your code, otherwise we're wasting our time spotting errors that don't exist in what you tested. Same for `''` not compiling as an empty character constant. – Peter Cordes May 10 '22 at 17:25
  • @NateEldredge Looks like you are right. Different sources seem to confirm that this function is "blocking" – Eugene Sh. May 10 '22 at 17:28
  • This also might need more complete code and details. With real-mode boot code, there are a lot of subtle ways that it can get messed up by incorrect compiler options, incorrect linking, loader code that doesn't load correctly or that doesn't correctly set things up for the C code, etc, etc. So any strange behavior could very well be caused by a bug in some completely different part of the project. – Nate Eldredge May 10 '22 at 17:29
  • I wrote 'a' in it, i have edited it for you. I mean u can replace '' with anything if u want. I My problem is also not that i cant compile it. the problem is a logical think i guess – Ett May 10 '22 at 17:29
  • I guess its the loop which was missing. assembly is just to fast – Ett May 10 '22 at 17:33
  • @Ett As Nate correctly said, my initial comment does not seem right. This 16H, 0 *should be waiting for a keystroke. But there is a "repetition" factor, that will repeat the keystrokes if pressed long time – Eugene Sh. May 10 '22 at 17:38
  • hmm but i am not sure how to fix that with C inline assembly also that loop stuff doesnt rly work out good – Ett May 10 '22 at 17:46
  • I solved it! wow i had to add asm(""); to it ._. But i have no idea why – Ett May 10 '22 at 20:00
  • 1
    Your first asm statement needs to be `asm volatile`, otherwise you're telling the compiler it can assume the output operand is the same every time (i.e. that it's a pure function of the input operand.) If you enabled optimization, that would let it get hoisted out of a loop. I don't think `asm("")` should make any difference; recent GCC treats a non-empty Basic Asm statement like `asm("# hi mom")` as having a `"memory"` clobber (which may stop some compile-time reordering), but an empty one is I think still nothing? It does still defeat some optimizations because it's implicitly volatile. – Peter Cordes May 10 '22 at 20:08
  • 1
    *My problem is also not that i cant compile it.* - then in future, don't post code that won't compile. You seem not to have realized the point of requiring a [mcve]. If you don't know exactly why your problem is happening (and then you wouldn't be asking), make sure your code is what you are actually using. Details are important for humans looking at code, as well as for computers running code. – Peter Cordes May 10 '22 at 20:25
  • with "my problem is also not that i cant compile" i mean it compiles and everything is fine. I was just hoping someone understand assembly deeper to help me without trying randomly stuff out but thx for trying – Ett May 10 '22 at 20:54
  • "thanks for trying"? Did you read the comment right before that, where I explained why `asm` without `volatile` explains the problem you're seeing (same character every time without actually re-running the `int`) and why `asm("")` might happen to fix, despite not being guaranteed to? I guess I shouldn't expect much from someone who expects people to help them without showing their actual code, instead posting something else with multiple distracting bugs and brushing off any suggestion that wasted our time. – Peter Cordes May 11 '22 at 03:18
  • Yes u did good, very nice! Volatile does its job as well! thanks :) – Ett May 12 '22 at 09:49

0 Answers0