Turbo C Strange Problem

G

Gabriel

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?

NOTE: if the function f has no code then the address is correctly
compiled, but if it as ANY code, like a variable declaration, then the
problem appears.

Thanks
 
B

Bartc

Gabriel said:
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.

The 000E isn't necessarily wrong, it depends on the segment registers. But
if you use a memory model where CS=DS=SS=ES then no it doesn't look right
(assuming exe2bin is doing it's job properly).

What happens when you add in this 0x10 offset to the source code (ie.
s[n+0x10])? How about varying the call, eg from f(h) to f(&h[0]) to
f("hello") and so on?

Of interest might be the contents of c.obj also, can you dump that? What
does -mt compilation switch do?
 
K

Keith Thompson

Gabriel said:
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.

<NITPICK>
That's null character, not NULL character. NULL (all-caps) refers
specifically to the macro that expands to a null *pointer* constant.
</NITPICK>

I'd say you've narrowed it down a bit *too* far. The program produces
no output, so a sufficiently clever compiler could reduce the whole
thing to the equivalent of ``int main(void) { }''. I doubt that Turbo
C 2.01 is that clever, but who knows what it could decided to do. (I
don't.)

Note that main returns int, not void. It's possible that TC2.01
accepts "void main()", but it's still a good habit to declare it
correctly. And since main returns int, it's a good idea to actually
return an int.

Try something like this:

#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++;
}
}

If that doesn't do it, try reproducing the problem (assuming there is
one) with a program that produces output rather than asking us to look
through assembly listings.
 
G

Gabriel

Im sorry i took so long to answer.

exe2bin works OK, because the output executable also has the address
corrupted. the bin and the exe are the same.

the -mt is to tell the compiler to use tiny model. i just noted that
in my post i missed the -c (i use it, i just forgot to write it), its
purpose is to compile and not link, so i can link in the second step.

if i try f(&h[0]) or f("hello") the problem persists, however calling
f this way: f(h + 0x10) fixes it.

Gabriel
 
G

Gabriel

Keith, im sorry for the assembly i just thought it would be helpful.

I tried your code but i cant get it compiled because i get undefined
external symbol when linking (putchar) even thou i have fixed my
turboc.cfg. I recall that once i got that same code to get compiled
(but i dont remember how) and it was OK, however if i try my original
code bit with int main the problem is still there. so i conclude that
stdio fixes it, but this is really strange.

Ill keep experimenting,

Gabriel
 
R

Richard Bos

Gabriel said:
Keith, im sorry for the assembly i just thought it would be helpful.

You're not being helpful by snipping all context.
I tried your code

What code? Which code? I see no CODE here.
but i cant get it compiled because i get undefined
external symbol when linking (putchar)

That's an ISO C function. If your implementation doesn't recognise it,
either get a real C compiler, or reinstall the one you have, and this
time get it right.

Richard
 
R

Richard Bos

Mark McIntyre said:
You are not linking against the library that contains putchar. Read your
toolset's documentation to find out how to correctly link.

The library that contains putchar is the Standard C library. If it isn't
linked against by default, something is wrong in his installation.
With responses like this, its no wonder CLC has a reputation for rudeness.

It's now rude to point out that he has somehow managed to break his
compiler's installation? Well, **** you too, buddy.

Richard
 
O

Old Wolf

I've reduced it to the following. My code in Turbo C is this:
and then i do exe2bin C.EXE to get the raw binary image.
So, the problem is the first line!
mov ax, 000E

Can you write a program that actually behaves
in some erratic way ? If the program's output
matches the expected output, then it doesn't
really matter what the assembly is (and it
shouldn't be taken as a sign of a bug).

BTW (to others in this thread) Turbo C 2.01
shipped in May 1989, so ANSI compliance should
not be expected.
 
D

Default User

Richard said:
Old Wolf said:



Given that fact, it's remarkable how conforming it actually is. Yes,
there are problem bits, but really they are few and far between, and
I believe that for the most part they comprise mere corner cases. The
most in-your-face violation seems to be the use of CLOCK_TCK rather
than CLOCKS_PER_SEC, which is hardly earth-shattering.

I used Turbo C for quite some time back in the day. Even after I
stopped using it as a compiler, I used the manual. It had good
descriptions of the library functions, along with whether they were
ANSI, "UNIX", or their own.




Brian
 
A

Antoninus Twink

I'm sure your service provider has an AUP about using offensive words in
your posts. You probably want to check on it because if you carry on
swearing someone (not me) will report you.

I know most clc'ers live in a strange fantasy world, but gimme a break!
I think you'll find very few ISPs have rules about their subscribers
using naughty words.
 
C

Coos Haak

Op Thu, 12 Jun 2008 19:36:22 +0100 schreef Mark McIntyre:
This doesn't follow, as you know well.

It is, I've just checked my installated TC 2.01 and putchar works.
Either the OP has a bad installed compiler or forgot to #include <stdio.h>
 
R

Richard

Mark McIntyre said:
This doesn't follow, as you know well.


I was referring to the unnecessarily sarcastic tone of your post which
was uncalled for and rude so early in a thread. Had you been replying
to the 23rd post from the same noob who had meantime got all agressive
about being corrected, I'd have said nothing


I'm sure your service provider has an AUP about using offensive words
in your posts. You probably want to check on it because if you carry
on swearing someone (not me) will report you.

That would be some interfering busy body like "Chuck" Falconer I dare
say.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,066
Latest member
VytoKetoReviews

Latest Threads

Top