Turbo C奇怪的问题 [英] Turbo C Strange Problem

查看:53
本文介绍了Turbo C奇怪的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述




我正在使用Turbo C 2.01并且我遇到了这个问题。


我已经减少了它以下。我在Turbo C中的代码如下:


void f(char *);


char h [] =" hello";


void main(){

f(h);

}


无效f(char * s){

int n = 0;

while(s [n]!= 0){

/ * do东西* /

n ++;

}

}


它只是一个功能这需要一个字符串作为一个参数,只是

循环,直到它找到终止的NULL字符。


我这样编译它(文件命名为cc) :


tcc -mt cc

tlink C.OBJ


然后我执行exe2bin C.EXE得到原始二进制图像。


.bin或.exe的反汇编(它们是相同的,但是

它更容易工作与.bin因为它没有turbo c

垃圾代码)如下:


0000 mov ax,000E < br $> b $ b 0003推斧

0004来电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]
$ b $ 00 0015 cmp byte ptr [bx + si],00

0018 jne 0011

001A pop si

001B pop bp

001C ret

001E''hello \''';你找我:)

所以,问题是第一行!


mov ax,000E


它没有指向位于001E的字符串,所以如果我用$ 16 $ b用十六进制编辑器改变那个字节,程序就可以了。

罚款。


我的问题是:为什么Turbo C提交此错误?我在做什么

出错了?


注意:如果函数f没有代码那么地址是正确的

编译,但如果它作为任何代码,如变量声明,则出现

问题。


谢谢

解决方案



" Gabriel" < ga *********** @ gmail.comwrote in message

news:01 ******************* *************** @ z66g2000 hsc.googlegroups.com ...




我正在使用Turbo C 2.01并且我遇到了这个问题。


我把它减少到了以下。我在Turbo C中的代码如下:


void f(char *);


char h [] =" hello";


void main(){

f(h);

}


无效f(char * s){

int n = 0;

while(s [n]!= 0){

/ * do东西* /

n ++;

}

}


它只是一个功能这需要一个字符串作为一个参数,只是

循环,直到它找到终止的NULL字符。


我这样编译它(文件命名为cc) :


tcc -mt cc

tlink C.OBJ


然后我执行exe2bin C.EXE得到原始二进制图像。


.bin或.exe的反汇编(它们是相同的,但是

它更容易工作与.bin因为它没有turbo c

垃圾代码)如下:


0000 mov ax,000E

0003推斧

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 \''';你找我:)


所以,问题是第一行!


mov ax,000E


它没有指向字符串,它位于001E,所以如果我用一个十六进制编辑器改变那个字节,程序就可以正常工作了。



000E并不一定是错的,它取决于段寄存器。但是如果你使用CS = DS = SS = ES的内存模型那么

那么它看起来不正确

(假设exe2bin正在做它的工作)正确)。


当你将这个0x10偏移量添加到源代码时会发生什么(即。

s [n + 0x10])?如何改变呼叫,例如从f(h)到f(& h [0])到

f(你好)等等?


感兴趣的可能也是c.obj的内容,你可以转储吗?什么

做-mt编译开关呢?


-

bartc


Gabriel< ga *********** @ gmail.comwrites:


我正在使用Turbo C 2.01和我坚持这个问题。


我把它减少到了以下。我在Turbo C中的代码如下:


void f(char *);


char h [] =" hello";


void main(){

f(h);

}


无效f(char * s){

int n = 0;

while(s [n]!= 0){

/ * do东西* /

n ++;

}

}


它只是一个功能它接受一个字符串作为一个参数,只是
循环,直到它找到终止的NULL字符。



< NITPICK>

这是空字符,不是空字符。 NULL(all-caps)特指

扩展为null *指针*常量的宏。

< / NITPICK>


我会说你已经把它缩小了一点*太远了。该程序产生

无输出,因此一个足够聪明的编译器可以将整个

的东西减少到相当于``int main(void){}''''。我怀疑Turbo

C 2.01是多么聪明,但谁知道它决定做什么。 (我

不要。)


注意main返回int,而不是void。 TC2.01

可能接受void main(),但它仍然是一个很好的习惯,可以正确地声明它b / b
。并且由于主要返回int,实际上是好主意

返回一个int。


尝试这样的事情:

#include< stdio.h>


void f(char *);


char h [] =" ;你好;


int main(无效){

f(h);

返回0;

}


void f(char * s){

int n = 0;

while(s [n ]!= 0){

putchar(s [n]);

putchar(''\ n'');

n ++ ;

}

}


如果不这样做,请尝试重现问题(假设有

one)一个产生输出的程序,而不是要求我们通过汇编列表查看




-

Keith Thompson(The_Other_Keith) ks***@mib.org < http://www.ghoti.net/ ~kst>

诺基亚

我们必须做点什么。这是事情。因此,我们必须这样做。

- Antony Jay和Jonathan Lynn,是部长


我很抱歉我这样做了很久才回答。


exe2bin工作正常,因为输出可执行文件也有地址

已损坏。 bin和exe是相同的。


-mt是告诉编译器使用小模型。我只是注意到

在我的帖子中我错过了-c(我用它,我只是忘了写它),它的

的目的是编译而不是链接,所以我可以在第二步中链接。


如果我尝试f(& h [0])或f(hello)问题仍然存在,但是调用

f这样:f(h + 0x10)修复它。


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

解决方案


"Gabriel" <ga***********@gmail.comwrote in message
news:01**********************************@z66g2000 hsc.googlegroups.com...

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?

--
bartc


Gabriel <ga***********@gmail.comwrites:

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.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"


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


这篇关于Turbo C奇怪的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆