NASM 猜数字游戏出错

发布于 2024-10-18 04:26:28 字数 3116 浏览 3 评论 0原文

我决定创建一个简单的猜数字游戏,它使用 Linux 系统调用和一些 C 函数来提供更简单的界面。当我将 int 转换为字符串并在屏幕上打印正确的答案时,我似乎遇到了分段错误。

这是输出:

Enter A Number One Through Ten:" : 
3
Response did not match! The Answer Is:Segmentation fault

这是 C 代码:

// print.c
#include "/usr/include/stdio.h" 
#include "/usr/include/string.h"
#include "/usr/include/stdlib.h"
#include "/usr/include/time.h"
void print(const char* msg)
{
    printf(msg);
    return;
}
int compare(const char* str, const char* str2)
{
    int i = strcmp(str, str2);
    if (i == 0)
    {
        return 1;
    }
    else
    {
       return 0;
    }
}
int divide(int num, int dem)
{
    if (dem == 0)
    {
        printf("Undefined");
        return 0;
    }
    else {
        return (num / dem);
    }
}
int randnum(int maxn)
{

    if (maxn == 0)
    {
        maxn = 1;
    }
    srand(time(0));
    return rand() % maxn;
}
int stoi(const char* str)
{
    return atoi("str");
}
void itos(int n)
{

     char* buf = "5";
     int ret = sprintf(buf, "%i\n", n);
     if (ret == -1){
    printf("Error!");
    return;
     }
     else{
    printf(buf);
     }
     return;

}

这是 NASM 代码:

      ; Declared C functions.
        extern print 
        extern compare
        extern divide
        extern randnum
        extern stoi
        extern itos
        section .data 
            msg: db 'Enter A Number One Through Ten:" : ', 10
            ml: equ $ - msg
            t: db 'Response did match!', 10
            tl: equ $ - t
            f: db 'Response did not match! The Answer Is:', 0
            fl: equ $ - f
            str2: db 'Hello'
        section .bss
            ;srnum: resb 255
            snum: resb 255
            rnum: resb 255
            num: resb 255
        section .text
            global _start ; Entry point function or label.
        _start:
            ; System call sys_write
            mov eax, 4
            mov ebx, 1
            mov ecx, msg
            mov edx, ml
            int 80h

; System call sys_read mov eax, 3 mov ebx, 0 mov ecx, snum mov edx, 255 int 80h ; Call stoi which converts string to int (parameter 1: is string to convert). push snum call stoi mov [num], eax mov ecx, esp sub ecx, 4 mov esp, ecx ; Call random push 10 call randnum mov [rnum], eax mov ecx, esp sub ecx, 4 mov esp, ecx ; Compare the two integers. mov eax, num cmp eax, [rnum] je true jne false true: ; Call sys_write mov eax, 4 mov ebx, 1 mov ecx, t mov edx, tl int 80h false: ; Segmentation fault is somewhere in this label mov eax, 4 mov ebx, 1 mov ecx, f mov edx, fl int 80h push rnum call itos ; Calling sys_exit with exit code (0 = ERROR_SUCCESS) mov eax, 1 mov ebx, 0 int 80h

I have decided to create a simple guessing number game that uses Linux system calls, and some C functions to provide a more simpler interface. I seem to get a segmentation fault when I convert the int to string and print the correct answeron the screen.

Here is the output:

Enter A Number One Through Ten:" : 
3
Response did not match! The Answer Is:Segmentation fault

Here is the C code:

// print.c
#include "/usr/include/stdio.h" 
#include "/usr/include/string.h"
#include "/usr/include/stdlib.h"
#include "/usr/include/time.h"
void print(const char* msg)
{
    printf(msg);
    return;
}
int compare(const char* str, const char* str2)
{
    int i = strcmp(str, str2);
    if (i == 0)
    {
        return 1;
    }
    else
    {
       return 0;
    }
}
int divide(int num, int dem)
{
    if (dem == 0)
    {
        printf("Undefined");
        return 0;
    }
    else {
        return (num / dem);
    }
}
int randnum(int maxn)
{

    if (maxn == 0)
    {
        maxn = 1;
    }
    srand(time(0));
    return rand() % maxn;
}
int stoi(const char* str)
{
    return atoi("str");
}
void itos(int n)
{

     char* buf = "5";
     int ret = sprintf(buf, "%i\n", n);
     if (ret == -1){
    printf("Error!");
    return;
     }
     else{
    printf(buf);
     }
     return;

}

Here is the NASM Code:

      ; Declared C functions.
        extern print 
        extern compare
        extern divide
        extern randnum
        extern stoi
        extern itos
        section .data 
            msg: db 'Enter A Number One Through Ten:" : ', 10
            ml: equ $ - msg
            t: db 'Response did match!', 10
            tl: equ $ - t
            f: db 'Response did not match! The Answer Is:', 0
            fl: equ $ - f
            str2: db 'Hello'
        section .bss
            ;srnum: resb 255
            snum: resb 255
            rnum: resb 255
            num: resb 255
        section .text
            global _start ; Entry point function or label.
        _start:
            ; System call sys_write
            mov eax, 4
            mov ebx, 1
            mov ecx, msg
            mov edx, ml
            int 80h

; System call sys_read mov eax, 3 mov ebx, 0 mov ecx, snum mov edx, 255 int 80h ; Call stoi which converts string to int (parameter 1: is string to convert). push snum call stoi mov [num], eax mov ecx, esp sub ecx, 4 mov esp, ecx ; Call random push 10 call randnum mov [rnum], eax mov ecx, esp sub ecx, 4 mov esp, ecx ; Compare the two integers. mov eax, num cmp eax, [rnum] je true jne false true: ; Call sys_write mov eax, 4 mov ebx, 1 mov ecx, t mov edx, tl int 80h false: ; Segmentation fault is somewhere in this label mov eax, 4 mov ebx, 1 mov ecx, f mov edx, fl int 80h push rnum call itos ; Calling sys_exit with exit code (0 = ERROR_SUCCESS) mov eax, 1 mov ebx, 0 int 80h

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

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

发布评论

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

评论(3

帅的被狗咬 2024-10-25 04:26:28

这段代码有一个问题:

char* buf = "5";
int ret = sprintf(buf, "%i\n", n);

buf是一个指向只读内存的指针,而sprintf希望能够修改它的内容。
您应该将 buf 更改为数组:char buf[20] (或 20 以外的某个任意大的数字,足以容纳您想要的内容)

There is a problem with this code:

char* buf = "5";
int ret = sprintf(buf, "%i\n", n);

buf is a pointer to readonly memory, and sprintf wants to be able to modify its contents.
You should change buf to an array: char buf[20] (or some number other than 20 that is arbitrarily large enough to hold your desired contents)

泡沫很甜 2024-10-25 04:26:28
void itos(int n)
{

     char* buf = "5";

在 buf 中,您有 2 个字符的空间(五个字符和 \0),

但是在这里:

int ret = sprintf(buf, "%i\n", n);

您在其中插入至少 3 个字符、至少一位数字、换行符 \n,然后是 \0。

以这种方式修改文字字符串也是不正确的。您可以通过以下方式声明文字字符串的堆栈副本:

char buf[] = "5"; // This sample will fail anyway, use a larger string...

或者更好的是一个足以容纳几个数字的空数组:

char buf[1024];
void itos(int n)
{

     char* buf = "5";

In buf you have space for 2 chars (the five and \0)

But here:

int ret = sprintf(buf, "%i\n", n);

you insert in it at least 3 chars, at least one digit of the number, the break line \n, and then \0.

Also is incorrect to modify a literal string this way. You can declare a stack copy of a literal string in the next way:

char buf[] = "5"; // This sample will fail anyway, use a larger string...

Or better just an empty array big enougth for several digits:

char buf[1024];
我不是你的备胎 2024-10-25 04:26:28

在函数 itos() 中,您尝试修改字符串文字 "5"。字符串文字是不可修改的(在这种情况下,您的操作系统将它们存储在映射为只读的内存中)。

在这种情况下,您的 itos() 函数不必要地复杂 - 您只需将其替换为:

void itos(int n)
{
     printf("%i\n", n);
}

(..或者您可以直接从 asm 代码调用 printf() )。

In your function itos(), you are attempting to modify the string literal "5". String literals are non-modifiable (in this case, your OS stores them in memory mapped as read-only).

In this case, your itos() function is needlessly complicated - you could simply replace it with:

void itos(int n)
{
     printf("%i\n", n);
}

(..or you could just directly call printf() from your asm code).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文