进行操作系统时通过参考的错误

发布于 2025-01-23 17:55:31 字数 1363 浏览 3 评论 0原文

我正在制造一个操作系统,并已启动到C中的64位内核。我制作了一个正在起作用的打印功能,并且正在尝试制作一个函数以将十六进制值转换为字符串,以便我可以打印它们。我的代码引起了引导循环,但是当我编译完全相同的代码以正常运行的Linux时,它可以完美地运行。相关代码:

int logarithm(double value, int base, int* output) {
    int i = 0;

    while (value > 1) {
        value /= base;
        i++;
    }

    *output = i;
}

int power(int value, int power, int* output) {
    if (power == 0) {
        value = 1;
    } else {
        for (int i = 0; i < (power - 1); i++) {
            value *= value;
        }
    }

    *output = value;
}

void hexToStr(unsigned int hex, char** string) {
    int hexLength = 0;
    logarithm((double)hex, 16, &hexLength);
    char output[hexLength];
    output[hexLength] = 0;

    int powerValue = 0;
    for (int i = 0; i < hexLength; i++) {
        power(16, i, &powerValue);
        output[hexLength - i - 1] = (hex & (powerValue * 15)) / powerValue + '0';
    }

    *string = output;
}

如果我将hextoStr()函数代码更改为此(删除对数()和power()power()函数的需求通过硬编码值的字符串函数),则它在Linux和My My kernel中起作用:

void hexToStr(unsigned int hex, char** string) {
    int hexLength = 10;
    char output[hexLength];
    output[hexLength] = 0;

    int powerValue = 0;
    for (int i = 0; i < hexLength; i++) {
        output[hexLength - i - 1] = 'A';
    }

    *string = output;
}

有关为什么要提出的任何建议这会发生吗?

I am making an os and have booted into a 64 bit kernel made in c. I have made a print function which is working and am trying to make a function to convert hex values to string so I can print them. My code is causing boot loops, yet when I compile the exact same code to run normally in linux it works perfectly. The relevant code:

int logarithm(double value, int base, int* output) {
    int i = 0;

    while (value > 1) {
        value /= base;
        i++;
    }

    *output = i;
}

int power(int value, int power, int* output) {
    if (power == 0) {
        value = 1;
    } else {
        for (int i = 0; i < (power - 1); i++) {
            value *= value;
        }
    }

    *output = value;
}

void hexToStr(unsigned int hex, char** string) {
    int hexLength = 0;
    logarithm((double)hex, 16, &hexLength);
    char output[hexLength];
    output[hexLength] = 0;

    int powerValue = 0;
    for (int i = 0; i < hexLength; i++) {
        power(16, i, &powerValue);
        output[hexLength - i - 1] = (hex & (powerValue * 15)) / powerValue + '0';
    }

    *string = output;
}

If I change the hexToStr() function code to this (removing the need for logarithm() and power() functions by hardcoding values for the string), it works in both linux and my kernel:

void hexToStr(unsigned int hex, char** string) {
    int hexLength = 10;
    char output[hexLength];
    output[hexLength] = 0;

    int powerValue = 0;
    for (int i = 0; i < hexLength; i++) {
        output[hexLength - i - 1] = 'A';
    }

    *string = output;
}

Any suggestions as to why this would happen?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

沉默的熊 2025-01-30 17:55:31

提出的代码调用了未定义的行为。例如,让我们

void hexToStr(unsigned int hex, char** string) {
    int hexLength = 10;
    char output[hexLength];
    output[hexLength] = 0;

    int powerValue = 0;
    for (int i = 0; i < hexLength; i++) {
        output[hexLength - i - 1] = 'A';
    }

    *string = output;
}

在此分配语句中考虑此功能:

    output[hexLength] = 0;

由于有效的索引范围为[0,hexlength),因此数组之外有书面数据。

或该函数通过引用本地数组将指针传递给函数的指针,该 在退出该功能后不会还活着。因此,返回的指针将具有无效的值。

另一个示例函数的结果值power当参数value等于3时等于3将等于81,而不是27,由于此循环中的分配说明。

    for (int i = 0; i < (power - 1); i++) {
        value *= value;
    }

此外,尽管其返回类型并非无效,但该函数什么也没返回。

int power(int value, int power, int* output) {

同样,这种表达

(hex & (powerValue * 15)) / powerValue + '0'

没有意义。

The presented code invokes undefined behavior. For example let's consider this function

void hexToStr(unsigned int hex, char** string) {
    int hexLength = 10;
    char output[hexLength];
    output[hexLength] = 0;

    int powerValue = 0;
    for (int i = 0; i < hexLength; i++) {
        output[hexLength - i - 1] = 'A';
    }

    *string = output;
}

In this assignment statement:

    output[hexLength] = 0;

there is written data outside the array because the valid range of indices is [0, hexLength).

Or the function sets a pointer passed to the function by reference to the local array output that will not be alive after exiting the function. So the returned pointer will have an invalid value.

Another example the result value of the function power when the parameter value is equal to 3 and the parameter power is equal to 3 will be equal to 81 instead of 27 due to the assignment statement in this for loop.

    for (int i = 0; i < (power - 1); i++) {
        value *= value;
    }

Moreover the function returns nothing though its return type is not void.

int power(int value, int power, int* output) {

Also this expression

(hex & (powerValue * 15)) / powerValue + '0'

does not make a sense.

給妳壹絲溫柔 2025-01-30 17:55:31

需要使SSE单元与浮子和双打一起工作。以及更改值的传递方式。工作代码:

void log(float value, float base, uint64_t* output) {
    uint64_t i = 0;

    while (value >= 1) {
        value /= base;
        i++;
    }

    *output = i;
}

void pow(uint64_t value, uint64_t exponent, uint64_t* output) {
    uint64_t result = 1;

    for (uint64_t i = 0; i < exponent; i++) {
        result = result * value;
    }

    *output = result;
}

void hexToStr(uint64_t hex, char* output) {
    uint8_t hexLen = 16;
    log((float)hex, (float)16, &hexLen);
    char result[hexLen + 3];
    result[0] = '0';
    result[1] = 'x';
    result[hexLen + 2] = 0;

    uint64_t powerValue = 1;
    for (uint8_t i = 0; i < hexLen; i++) {
        pow(16, i, &powerValue);
        result[hexLen - i + 1] = (hex & (uint64_t)(powerValue * (uint64_t)15)) / powerValue + '0';
    }

    for (uint8_t i = 0; i < hexLen + 3; i++) {
        switch(result[i]) {
            case ':':
                result[i] = 'A';
                break;
            case ';':
                result[i] = 'B';
                break;
            case '<':
                result[i] = 'C';
                break;
            case '=':
                result[i] = 'D';
                break;
            case '>':
                result[i] = 'E';
                break;
            case '?':
                result[i] = 'F';
                break;
        }
        output[i] = result[i];
    }
}

Needed to enable SSE unit to work with floats and doubles. As well as change how values are passed back. Working code:

void log(float value, float base, uint64_t* output) {
    uint64_t i = 0;

    while (value >= 1) {
        value /= base;
        i++;
    }

    *output = i;
}

void pow(uint64_t value, uint64_t exponent, uint64_t* output) {
    uint64_t result = 1;

    for (uint64_t i = 0; i < exponent; i++) {
        result = result * value;
    }

    *output = result;
}

void hexToStr(uint64_t hex, char* output) {
    uint8_t hexLen = 16;
    log((float)hex, (float)16, &hexLen);
    char result[hexLen + 3];
    result[0] = '0';
    result[1] = 'x';
    result[hexLen + 2] = 0;

    uint64_t powerValue = 1;
    for (uint8_t i = 0; i < hexLen; i++) {
        pow(16, i, &powerValue);
        result[hexLen - i + 1] = (hex & (uint64_t)(powerValue * (uint64_t)15)) / powerValue + '0';
    }

    for (uint8_t i = 0; i < hexLen + 3; i++) {
        switch(result[i]) {
            case ':':
                result[i] = 'A';
                break;
            case ';':
                result[i] = 'B';
                break;
            case '<':
                result[i] = 'C';
                break;
            case '=':
                result[i] = 'D';
                break;
            case '>':
                result[i] = 'E';
                break;
            case '?':
                result[i] = 'F';
                break;
        }
        output[i] = result[i];
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文