Hi,

I'm using Turbo C 2.01 and im stuck with this problem.

I've reduced it to the following. My code in Turbo C is this:

void f(char *);

char h[] = "hello";

void main() {
	f(h);
}

void f(char *s) {
	int n = 0;
	while (s[n] != 0) {
		/*do something*/
		n++;
	}
}

It's just a function that takes a string as an argument and merely loops till it finds the terminating NULL character.

I compile it like this (the file is named c.c):

tcc -mt c.c
tlink C.OBJ

and then i do exe2bin C.EXE to get the raw binary image.

The disassembly for either the .bin or .exe (they are the same, but it's easier to work with the .bin because it doesn't have the "turbo c junk code") is the following:

0000	mov ax, 000E
0003	push ax
0004	call 0009
0007	pop cx
0008	ret
0009	push bp
000A	mov bp, sp
000C	push si
000D	xor si, si
000F	jmp 0012
0011	inc si
0012	mov bx, [bp+04]
0015	cmp byte ptr [bx+si], 00
0018	jne 0011
001A	pop si
001B	pop bp
001C	ret
001E	'hello\0' ;you get me :)

So, the problem is the first line!

mov ax, 000E

It doesn't point to the string, which is located in 001E, so if i change that byte with a hexadecimal editor the program works just fine.

My question is: why does Turbo C commit this error? Am i doing something wrong?

Thanks

Recommended Answers

All 26 Replies

It's just a function that takes a string as an argument and merely loops till it finds the terminating NULL character.
[...]

Am i doing something wrong?

Yes. To find the terminating char, you did this: while (s[n] != 0) But 0 and the string-terminating-char aren't the same. So change it to: while (s[n] != '\0') Now your array will stay within it's limits.
Just a hint: You can also use strlen() which does the exact same thing, but with a lot of error checking.

Also: this thread is in the wrong forum. I'll ask if it can be moved.

dont use trubo c. If you search this forum you would know why.

turbo C is a piece of crap.

use the GCC compiler (free) or MSVC compiler (free) with the Code::Blocks IDE (free).

Thanks for replying.

niek_e, you are right about the comparing but thats not the problem. It seems to me that you misunderstood my post, if you look at the disassembly, the array position is not ok when passed to the function, independent of what the function does.

I need to use Turbo C, so i think this thread should be in Legacy, i dont know why it was moved, because the discussion isnt about C but The Turbo C compiler itself.

hi. Paolo. i wish i had an answer for you. i would try, but i don't have the compiler to replicate it with.

well, i can see now you're not the typical Turbo C user who just doesn't know any better. ... so if you don't mind, i'd like to know why do you need to use it? curious.

jephthah, thank you very much for your interest.

Im developing an operating system (if you can call it that) as a project of my own and just for personal use. Im really excited about this.

I already have my bootloader coded in nasm and it works.

Now im working on the kernel mixing Turbo C and nasm. I want to stay in 16 bit and thats why i use Turbo C, i have tried other compilers (there arent many 16 bit C compilers for windows) but they didnt work or maybe i couldnt get them to work.

The problem is not mixing Turbo C with nasm or the fact that the program will not sit on dos whatsoever. If i just wanted to write a program with a function that takes an array or a pointer as a parameter and compile-link it with the tiny memory model, i couldnt. I really have no clue of why the address is not correct.

Thanks,

Gabriel

The program you're writing will work on ANY C compiler, even piece of crap compilers, which Turbo C is not one of. It pisses me off every time someone denegrates good compilers just because they are older. If they do exactly what the user needs, it's fine. It just can't do advanced 32bit stuff that the user obviously doesn't need. It still is C. It still works fine. And TC can still do things none of the current compilers can do.

I agree upgrading should be considered, but is not necessary. And definitely TC should not be put down.

OK, i knew about that already and thats why im using Turbo C.

But im still having the problem i posted at the begging! Anyone can help me with that? If somebody wants my messenger to instruct me easier ill be happy to pm it.

Or maybe someone can recommend me another 16 bit compiler, and how to compile and link the project (i have watcom but i havent been able to get it to work).

Thanks,

Gabriel

I don't have Turbo C 2.0, but this runs fine in Turbo C/C++ ver. 1.01, as a C program. Note int main and the include header.

IIRC Turbo C 2.0 came before Turbo C/C++, but it's been a long time.

#include <stdio.h>  

void f(char *);

char h[] = "hello";
  
int main() {
   int gar;
   f(h);
   gar = getchar(); gar++;
   return 0; 
}
void f(char *s) {
   int n = 0;
  
   while (s[n] != '\0') {
      /*do something*/
      putchar(s[n++]);
   }
}

How are you compiling? Directly from the environment or using tcc and tlink separately?

I want to do it the second way and without using stdio. So i tried like this both with Turbo C 2.01 and with Turbo C++ 1.01 and both have the same problem.

If anyone wants to help me with this here is my address <snip url> I can send you a copy of Turbo C and Turbo C++ for you to try it yourself.

Thanks

I compiled from the IDE.

If using int main doesn't help correct your program's starting address, can you just set the address, explicitly?

commented: good spot! +3

Yes, i can set the address using a hexadecimal editor, but that code i posted is just the abstraction of the problem. In my actual program i will have lots of arrays/pointers to pass to functions and i cant just change them every time i compile.

This is REALLY odd because i dont think that borland would release a buggy compiler that just messes up addresses of array/pointer parameters. I really dont know what else to try.

Thanks,

Gabriel

wait a minute.... you're using "void main()" ?? LOL ... how did we not see this. You know, of course, "void main()" is undefined.

so it's no wonder you're having undefined behavior.

i dont think that borland would release a buggy compiler

oh, it was a great compiler.... in 1989. now its just full of deprecated, non-ANSI functions and terribly non-portable. Borland's strategic business plan appears to hinge on an exclusive distribution contract with the government of India, but other than that, i can't imagine why anyone would choose to use it.


.

My version, which has int main, instead of void main, works fine using: "tcc <filename>

And I did notice it! :)

yeah, you did. good spot. :) ... by "we" i meant the various "veteran" forum members who have passed through this thread over the past week. (where's Salem, anyhow??)


(i think what happened here is everyone saw "Turbo C" and said PFFFT... or maybe we all got skeered by the assembly :P )


.

Ok, i see what you mean, but this doesnt fix the problem.

This is exactly what im doing:

void f(char *);

int main() {
	f("hello");
	return 0;
}

void f(char *s) {
	int i;
	for (i = 0; s[i] != '\0'; i++) {
		/*foo*/
	}
}

I compile this way (either with Turbo C or C++ the output is the same):

tcc -mt -c source.c
tlink source.obj

And then:

exe2bin source.exe source.bin

(Im compiling and linking in two steps because i will be mixing C with assembly but this has nothing to do with the problem because im still not doing it and the address is still incorrect)

The result is:

0000 push bp
      0001 mov bp, sp
      0003 mov ax, 0006
      0006 push ax
      0007 call 0011
      000A pop cx
      000B xor, ax, ax
      000D jmp 000F
      000F pop bp
      0010 ret
      0011 push bp
      0012 mov bp, sp
      0014 push si
      0015 xor si, si
      0017 jmp 001A
      0019 inc si
      001A mov bx, [bp+04]
      001D cmp byte ptr [bx+si],00
      0020 jne 0019
      0022 pop si
      0023 pop bp
      0024 ret
      0025 ;the opcode is 00, its a null
      0026 'hello\0'

So, again, at the start:

mov ax, 0006

should be:

mov ax, 0026

where the string is located.

Maybe you can compile it yourself, what im noticing is that the last digit of the hex location is always correct.

Gabriel

sorry, man, i don't have Turbo C.

one time, i thought about installing it for fun, but they wanted a whole bunch of registration and personal info B.S.

which just reinforced the fact that i didn't want their crap on my hard drive, anyhow.

The -mt option gives me this "warning: No Stack".

I don't believe the borland compiler is buggy, but I do believe you'll need to do some research, perhaps on a website dedicated to borland's legacy compilers, and see what's the right way to do this.

I'm new here. Do you have any old timer's who might remember how this is done with Turbo C, around? :)

Wish I could help you out, but I have never worked with separate compilation, and linking.

i cant even get exe2bin to work on my Vista laptop. it's a native DOS application, for one thing.

what kind of hardware and OS are you running/compiling all this on? If you're trying to do 16-bit computing on modern machines, you're gonna have major difficulties.

i dont even trust EXE2BIN to work correctly, there's so many limitations of that program as it is, and now you want it to disassemble a third-party executable.

i think this approach (Turbo C + MSDOS Exe2Bin) is just doomed from the start.

im using xp 32 bit.

exe2bin is not the problem, i just use it to make debugging easier. the executable tlink outputs is exactly the same as the raw binary image made with exe2bin. so, if you cant get exe2bin to work just forget about it.

yes adak, the warning is thrown but its not a problem as ive researched.

and jephthah, youve certainly helped me out sice the begging and i really appreciate it. if you want i can send you a copy of tcc.exe and tlink.exe (no installation required) or upload them to some server you like, if youre still interested in this thread, of course.

Thanks to all

By the way, maybe someone knows another C/C++ 16bit compiler i can use

Gabriel

i would suggest that your problem is that you're on a Win32 OS, with hardware that was designed for a 32 bit OS, trying to use a 16-bit deprecated compiler along with an old MSDOS disassembler.

that you're having "problems" is no surprise.

i appreciate your offer for the compiler, and i thought about taking you up on it, but im afraid im going to have to pass.

for a moment i imagined it would be useful to help all those folks from the subcontinent who are forced to use Turbo C for gods-only-know-why... but then i come back to reality, and it really is the last thing i need to do, plus i would have to get all of Turbo C's non-ANSI deprecated libraries and all that, and honestly i just don't have time to deal with such antiquated stuff. I'd rather just sit on the sidelines and yell at them to join the 21st century. or hell, even join the mid-1990's.

but, thanks though.. and good luck. sorry, i dont know of any 16-bit compilers other than i might randomly find on google.


EDIT: To the Moderators... I think this DOES belong in the "Legacy Forum" as the OP originally placed it. He's obviously not getting much help here, other than pedantic ramblings.

jephthah thank you very much for your support, really!

if someday i get a solution ill let you know.

Gabriel

can u plz share some details of the loader or the components required to creare an OS.
I am just curious abt that.
How can i create a program in either C (TC or else) or ASM which can run without OS, I mean I would put it on the CD, & boot my PC from the CD.....
plz give any ideas or any links if you have regarding these ...

Paolo,
Have you successfully used this process before and it's just this program that doesn't work? If so, I'm not sure what's happening. If not, as a guess, TC2 is compiling the program in a form that cannot be converted into a .COM file. There are (were?) restrictions that make most .EXE files not .COM compatible.

I have started using Turbo C/C++ recently and i could never get this code to work, i cant pass arrays or pointers to functions because the addresses get messed up.

I once found a code that worked but i cant compile it anymore:

#include <stdio.h>

void f(char *);

char h[] = "hello";

int main(void) {
      f(h);
      return 0;

}

void f(char *s) {
      int n = 0;
      while (s[n] != 0) {
              putchar(s[n]);
              putchar('\n');
              n++;
      }

}

This works, but i cant compile it anymore, tlink gives me an error (putchar unresolved external).

Im now seeking for someone whos willing to try and compile the original code on their machine to see the results, i can send Turbo C/C++ via email or upload somewhere.

Thanks

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.