Author Topic: Mixing C and Assembly parameter problem  (Read 22194 times)

Offline isywum

  • Jr. Member
  • *
  • Posts: 38
Re: Mixing C and Assembly parameter problem
« Reply #15 on: March 18, 2012, 08:35:09 PM »
Wow again!
I found the paramter at [ebp+66].
Anything is wrong here... :D
I'm gonna safe the files this time.
I think there's just one big problem (linker, compiler or assembly).
Maybe I should try another compiler.

EDIT:
A second paramter destroys the whole esp. I even can't return.
« Last Edit: March 18, 2012, 08:38:10 PM by isywum »

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Mixing C and Assembly parameter problem
« Reply #16 on: March 18, 2012, 09:32:47 PM »
Lemmee get this straight... You're still in 16-bit mode, right? Or have you switched to 32-bit pmode?

It looks to me like your linker is doing what you ask of it. It looks to me like gcc is doing what it does - producing 32-bit code. I understand gcc can be tortured into producing 16-bit code, if you do it right. I just did a quick experiment with Nasm, using "-f elf" but adding "bits 16" at the top of the code. It looks like 16-bit code. Using "use16" as a section attribute is rejected. So you "might" be able to get 16-bit code out of the tools you're using, although I think it's the "hard way". I'll have to check the syntax for gcc - maybe later. If you've switched the CPU to 32-bit pmode, the BIOS interrupt isn't going to work, and the DOS interrupt isn't going to work in any case (unless you've provided it).

What is the purpose of introducing C at this early stage? I don't see that it's going to give you much advantage until you've got some libraries written. Maybe I don't see the point of it just because I don't "like" C very much...

Best,
Frank


Offline isywum

  • Jr. Member
  • *
  • Posts: 38
Re: Mixing C and Assembly parameter problem
« Reply #17 on: March 19, 2012, 01:05:33 PM »
I just read a great tutorial (unfortunately german) an [bp+4] works now!
That's great. I hope [ebp+8] in the PM is going to work.
That's what I just did:
- [BITS 16] at the top of every file
-
Code: [Select]

    mov ax, cs
    mov ds, ax
    mov ss, ax
    mov ax, 0xFFF0
    mov sp, ax
in 'kernel.asm'
-
Code: [Select]
    push bp
    mov bp, sp
    mov al, [bp+4]
    mov ah, 0x0E
    int 0x10
    pop bp
    ret
in 'print.asm'
Wow, great!
Thank you so much, Frank! :)

EDIT:
I'm gonna tell you about [ebp+8] in Protected Mode.

EDIT2:
What a pity... I can use my function only once. The second time there's no parameter.
I hope you can help me once again. :D
« Last Edit: March 19, 2012, 01:26:46 PM by isywum »

Offline isywum

  • Jr. Member
  • *
  • Posts: 38
Re: Mixing C and Assembly parameter problem
« Reply #18 on: March 24, 2012, 12:31:40 PM »
I solved the problem now. :)
I added asm(".code16gcc\n"); in the first line of my kernel.c and changed bp to ebp, sp to esp and 4 to 8 and all works! I call the function as often as I want. Wow, I'm happy. :)
Thank you for your help, this is a great forum!

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Mixing C and Assembly parameter problem
« Reply #19 on: March 24, 2012, 01:01:56 PM »
Using "native" Linux gcc and ld, I found that ".code16" worked better than ".code16gcc". The latter was giving me a 32-bit "call" - still 16-bit code, with a 0x66 "operand size override". I also found that calling the parameter "int" gives a 32-bit parameter. I thought that calling the parameter(s) "short" might work better (assuming you want 16-bit). I haven't actually tried that.

If it works, it works, but I'm afraid you're getting an almost "random" mixture of 16-bit and 32-bit instructions. In any case, you were correct that you can force gcc to produce 16-bit code, so I learned something there!

Best,
Frank


Offline isywum

  • Jr. Member
  • *
  • Posts: 38
Re: Mixing C and Assembly parameter problem
« Reply #20 on: March 24, 2012, 02:04:34 PM »
Anyway, I'm gonna use the Protected Mode, so I shouldn't have that problems.
Thanks!

EDIT:
.code16 doesn't work... I don't get the paramters. :D
Do you know why?
« Last Edit: March 24, 2012, 02:07:54 PM by isywum »

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Mixing C and Assembly parameter problem
« Reply #21 on: March 24, 2012, 03:29:42 PM »
I really don't know exactly what you're doing, at this point. What I experimented with was some earlier code you posted. It has some "problems", but I imagine you've fixed them. I haven't actually tried any of this, just looked at the disassembly. It "looks like" it would work, as 16-bit code (although rather strange code). What I would do to actually "try" it would be to write up a bootsector which loads the code - somewhere - and jumps to it. I'm guessing you're trying this in an emulator, rather than actually booting to it from a floppy(?). "Should" work the same.

I can show you what I've got, I suppose...

start.asm
Code: [Select]
bits 16
global start

start:
extern main
call main

main.c
Code: [Select]
extern int paramter(int i);
extern void read();
extern void stop();

asm(".code16\n");
int main() {
if (paramter(9) == 9) {
read();
}
read();
stop();
return 0;
}

read.asm
Code: [Select]
bits 16
global read

read:
mov ah, 0x0
int 0x16
ret

paramter.asm
Code: [Select]
bits 16
global paramter

paramter:
push bp
mov bp, sp
mov al, [bp+8]
add al, 48
mov ah, 0x0E
int 0x10
mov ah, 0
pop bp
ret

stop.asm
Code: [Select]
bits 16
global stop

stop:
mov ah, 0x4C
int 0x21
ret

link.ld
Code: [Select]
OUTPUT_FORMAT("binary")
ENTRY(start)
phys = 0x00100000;
SECTIONS
{
  .text phys : AT(phys) {
    code = .;
    *(.text)
    *(.rodata)
    . = ALIGN(4096);
  }
  .data : AT(phys + (data - code))
  {
    data = .;
    *(.data)
    . = ALIGN(4096);
  }
  .bss : AT(phys + (bss - code))
  {
    bss = .;
    *(.bss)
    . = ALIGN(4096);
  }
  end = .;
}

Code: [Select]
00000000  E80D00            call word 0x10
00000003  0000              add [bx+si],al
00000005  0000              add [bx+si],al
00000007  0000              add [bx+si],al
00000009  0000              add [bx+si],al
0000000B  0000              add [bx+si],al
0000000D  0000              add [bx+si],al
0000000F  00                db 0x00
00000010  67668D4C2404      lea ecx,[dword esp+0x4]
00000016  6683E4F0          and esp,byte -0x10
0000001A  6766FF71FC        push dword [ecx-0x4]
0000001F  6651              push ecx
00000021  6683EC08          sub esp,byte +0x8
00000025  6766C70424090000  mov dword [dword esp],0x9
         -00
0000002E  E83F00            call word 0x70
00000031  6683F809          cmp eax,byte +0x9
00000035  7503              jnz 0x3a
00000037  E82600            call word 0x60
0000003A  89F6              mov si,si
0000003C  8DBD0000          lea di,[di+0x0]
00000040  E81D00            call word 0x60
00000043  E83A00            call word 0x80
00000046  66B800000000      mov eax,0x0
0000004C  6683C408          add esp,byte +0x8
00000050  6659              pop ecx
00000052  67668D61FC        lea esp,[ecx-0x4]
00000057  C3                ret
00000058  0000              add [bx+si],al
0000005A  0000              add [bx+si],al
0000005C  0000              add [bx+si],al
0000005E  0000              add [bx+si],al
00000060  B400              mov ah,0x0
00000062  CD16              int 0x16
00000064  C3                ret
00000065  0000              add [bx+si],al
00000067  0000              add [bx+si],al
00000069  0000              add [bx+si],al
0000006B  0000              add [bx+si],al
0000006D  0000              add [bx+si],al
0000006F  00                db 0x00
00000070  55                push bp
00000071  89E5              mov bp,sp
00000073  8A4608            mov al,[bp+0x8]
00000076  0430              add al,0x30
00000078  B40E              mov ah,0xe
0000007A  CD10              int 0x10
0000007C  B400              mov ah,0x0
0000007E  5D                pop bp
0000007F  C3                ret
00000080  B44C              mov ah,0x4c
00000082  CD21              int 0x21
00000084  C3                ret
...padded to 4096

Your "paramter:" converts the number 9 to the character '9'. When this returns to the C code, this checks for 9, the number, not the character. This isn't going to work.

Your "stop:" uses int 21h. This isn't going to work.

The "phys" in your "link.ld" looks a little high to me. I doubt if this is going to work (although I doubt if it makes any difference at this point). I think you'd need to enable a20, and alter the "limit" to make this actually work at "some_segment:0x100000". But I don't know how/where you're actually loading this code, and what you've done first, so I could be wrong about that. You keep saying that you're going to use Protected Mode, but you haven't actually switched to pmode yet, right?

I don't know if this is any help or not.

Best,
Frank


Offline isywum

  • Jr. Member
  • *
  • Posts: 38
Re: Mixing C and Assembly parameter problem
« Reply #22 on: March 24, 2012, 03:51:24 PM »
Yeah, that code is really old and it was just a test file (not the OS).
I'm trying to understand the Protected Mode but I couldn't so far...
This is my new code:
Code: [Select]
asm(".code16gcc\n");
extern void print();
extern void restart();
extern char read();
int printString(char* szString);

int main() {
char szString[] = "Hello world!";
printString(szString);
while(read() != 'r');
restart();
return 0;
}

int printString(char* szString) {
short i=0;
while (i != 2)
{
print(szString[i]);
i=i+1;
}
return 0;
}
But it just always shows HaHaHaHa and so on. I don't get why the function doesn't return.

My new print.asm is:
Code: [Select]
[BITS 16]
global print

print:
push ebp
mov ebp, esp
mov al, [ebp+8]
mov ah, 0x0E
int 0x10
pop ebp
ret

I know that this is a strange mixing assembly and C but until I'm in the Protected Mode I'd like to solve it like this.
Thank you!

EDIT:
asm(".code16\n"); makes the OS to return from the function but I don't get a parameter.
« Last Edit: March 24, 2012, 03:52:58 PM by isywum »

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Mixing C and Assembly parameter problem
« Reply #23 on: March 24, 2012, 05:35:04 PM »
Well... if you're using ".code16gcc" and ebp in the asm file, I would "expect" the first parameter at [ebp + 8]. You might try "o32 ret" to get it to return(?).

If you're using ".code16" and ebp, I would "expect" the first parameter to be at [ebp + 6]. I would "expect" it to return okay. If you're using ".code16" and bp. I would "expect" the first parameter to be at [bp + 4] as it "should" be in 16-bit code. But I didn't even know you could get 16-bit code out of gcc, so... Who knows?

Best,
Frank


Offline isywum

  • Jr. Member
  • *
  • Posts: 38
Re: Mixing C and Assembly parameter problem
« Reply #24 on: March 24, 2012, 05:58:30 PM »
Wow, you are genius! o32 ret works! That's great. .code16 and ebp+6 doesn't work but who cares? Can you just tell me what the difference between ret and o32 ret is?

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Mixing C and Assembly parameter problem
« Reply #25 on: March 24, 2012, 06:27:44 PM »
"o32 ret" will cause Nasm to generate a 0x66 "operand size override prefix" before the "ret" (0xC3). This will, in turn, tell the CPU to expect a 32-bit return address on the stack - which gcc apparently puts there if you use ".code16gcc". At least, I think that's what's happening...

Best,
Frank


Offline isywum

  • Jr. Member
  • *
  • Posts: 38
Re: Mixing C and Assembly parameter problem
« Reply #26 on: March 25, 2012, 10:08:36 AM »
Well, thank you. I don't have any problem with parameters right now but there's just another little problem. I know that's not a part of that subject but it's just a little one. Sometimes the size of the kernel.bin is too big. That happens for example if there a too long (many) strings.
char szWelcome[] = "Hello world!"; works but char szWelcome[] = "Hello world, welcome to my OS. Please press a key to start."; doesn't the size of the file is 8192 instead of 4092 bytes. When I change the padding there's a OS.iso but it doesn't work, it jsut craches. I hope you can help me. :)

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Mixing C and Assembly parameter problem
« Reply #27 on: March 25, 2012, 01:11:46 PM »
Well, you remember when we were having a problem with "too many call instructions"?

http://forum.nasm.us/index.php?topic=1307.0

As it turned out, the problem was something else (we never did figure out what). Could it be that this time you're really not loading enough sectors? What you showed me back then was loading 5 sectors. Maybe that's not enough with the longer strings? I'm just guessing, of course, but that's the first and most obvious thing that comes to mind.

Best,
Frank


Offline isywum

  • Jr. Member
  • *
  • Posts: 38
Re: Mixing C and Assembly parameter problem
« Reply #28 on: March 25, 2012, 02:00:00 PM »
You're right! It works with 18 sectors. Great! Thank you so much!