您好我正在尝试将我编写的C函数转换为汇编代码(SPARC arc),但不断收到分段错误(核心转储)错误。该函数应该将字符串转换为long值。我知道我已经测试了它并且它通过了所有测试,所以我正确地完成了C功能。这是我想要转换的C函数。
long strToLong(char *str, int base )
{
char *endptr;
errno = 0;
long num;
num = strtol(str, &endptr, base);
char holder[BUFSIZ];
/*if *endptr isn't '\0' then strtol didn't get to the end of the string
*so it wasn't a valid integer*/
if(*endptr != '\0')
{
(void)fprintf(stderr, "\n\t""'%s'" " is not an integer\n", str);
return 0;
}
/*if errno isn't 0 then an error occured so print out an error message*/
else if(errno != 0)
{
(void)snprintf(holder, BUFSIZ,"\n\tConverting \"%s\" base \"%d\"\n caused an ", str, base);
perror(holder);
return 0;
}
/*if no errors, then it was a valid integer so return the integer*/
return num;
}
这是我写的汇编代码。
.global strToULong
.section ".data"
fmt1: .asciz "%s is not an integer\n" !ascii format
fmt2:
.asciz "Converting %s base %d\n" !ascii format
.section ".text"
strToULong:
save %sp, -( 92 + 1028) & -8, %sp
add %fp, -4, %o1
mov %i0, %o0
mov %i2, %o2
call strtol
nop
mov %o0, %l0
ld [%fp - 4], %l1
ldub [%l1], %l1
cmp %l1, %g0
be errno
nop
set stdError, %o0
ld [%o0], %o0
set fmt1, %o1
mov %i0, %o2
call fprintf, 3
nop
errno:
mov %l0, %i0
set errno, %l2
ld [%l2], %l2
cmp %l2, %g0
be return
nop
add %fp, -1028, %o0
mov 1024, %o1
set fmt2, %o2
mov %i0, %o3
mov %i1, %o4
call snprintf
nop
add %fp, -1028, %o0
call perror
nop
mov 0, %i0
return:
ret
restore
我调试了程序,当我调用strtol函数时会出现seg错误。我不确定我做错了什么,我想我正确地传递了参数,但我仍然得到了这个错误。哦,在我的主要部分,我有一些声明像FILE * StdError = stderr的东西,将stderr作为参数传递给fprintf。
任何帮助都会得到满足。
答案 0 :(得分:1)
你在那里遇到了几个不同的问题,但你很容易修复的问题就是你访问errno的方式。你不应该有一个名为errno的分支,因为你也有一个全局var errno,这会引起一些混乱。
由于errno是一个全局变量,因此将errno加载到寄存器中应如下所示:
set errno, %l0 !sets %o0 to a pointer to errno
st %g0,[%l0] !set errno to 0
set %i0, %o0 !move str to output
set endptr, %01 !move endptr to output (defined above in .section ".data")
set %i1, %o2 !move base to output
call strtol,2 !calls strtol with given inputs
nop
ld [%l0], %l1 !loads the value at errno into %l1
在此示例中,%l0包含指向errno的指针,%l1在调用strtol后将值保存在errno。然后您可以使用以下错误检查:
cmp %l1,%g0 !compares errno to 0
be endif
nop
/* if body */
endif:
/* continued code */
这应该可以让你解决一些问题。当你正在编写汇编时,真的很有帮助就像疯了一样评论它们!在每条线之后,在顶部的一个区块中,您可以跟踪当地的变量。装配看起来并不那么简单,所以它确实有帮助。