【问题标题】:Problems with ATOI in x86 NASM Linux assemblyx86 NASM Linux 程序集中的 ATOI 问题
【发布时间】:2013-03-18 18:56:06
【问题描述】:

我不明白如何将字符串转换为整数。

这是家庭作业,但是我不想要这个问题的答案——(AKA 正确代码)。如果有人能解释我做错了什么,我将不胜感激! :(

提前致谢!!!

我在 32 位虚拟机上运行 Ubuntu 12.04。

我编译:

nasm -f elf proj2.asm

我链接到:

gcc -o proj2 proj2.o

然后运行它:

./proj2

它显示第一个数字,但当我尝试使用 atoi 时,出现分段错误。

我有一位老师希望我们这样做:

  1. 从这样排列的文本文件中读取数字:

    4
    5
    4
    2
    9
    

(每个整数前都有空格)

按照他的指示:“请务必将七 (7) 个字符读入缓冲区以获取整行。这些是代表数字的五个字符以及字符 CR 和 LF。CR 是十六进制的回车符代码0x0D,LF 是十六进制代码0x0A 的换行符。")

我已删除文件中的空格,并尝试以这种方式读取,但没有帮助。

整数将被读取到堆栈上的一个数组中,最大整数数为 250。但这不是问题:/

以下是我目前的代码。

    BUFFERSIZE equ 10

section .data
    file_name: db "/home/r/Documents/CS/project2/source/indata.txt", 0x00
    file_mode: db "r", 0x00
    output: db "%i",0xa
    test: db "hello world",10
    format: db "%u"
    numToRead: db 1
    temp: db "hi"
    num:db "1",0,0
section .bss
    fd:    resd 4
    length:    resd 4
    buffer resb BUFFERSIZE
                            ;i was trying to use buffers and just
                            ;read through each character in the string, 
                            ;but i couldn't get it to work
section .text 
 extern fopen
 extern  atoi
 extern printf
 extern fscanf

 extern fgets
 extern getc
 extern fclose
 global main

main: 
                    ;setting up stack frame
    push    ebp
    mov     ebp, esp 

                    ;opens file, store FD to eax
    push    file_mode
    push    file_name
    call    fopen

                    ;save FD from eax into fd    
    push    eax
    mov     ebx,eax
    mov     [fd],ebx

                    ;ebx holds the file descriptor
                    ;push in reverse order
    push    ebx
    push    numToRead
    push    temp
    call    fgets    

    push  eax
    call printf     ;prints length (this works, i get a 4. 
                    ;Changing the number in the file changes the number displayed. 
                    ;I can also read in several lines, just can't get any ints! 
                    ;(So i can't do any comparisons or loops :/ )


                    ;i shouldn't need to push eax here, right? 
                    ;It's already at the top of the stack from the printf
    ;pop  eax
    ;push eax
    call atoi
                        ;calling atoi gives me a segmentation fault error
    push eax
    call printf

    mov esp,ebp
    pop ebp 
    ret 

编辑: 有趣的是,我可以调用 atoi 就好了。那是我尝试的时候

push eax
call atoi 
push eax
call printf 

我得到分段错误。

【问题讨论】:

  • 您的输入文件使用 Windows 样式的 CR-LF 行结尾而不是 Unix/Linux 样式的 LF 行结尾?
  • 我相信是这样,我想我不确定有什么区别——它们不一样吗?我不确定它是否相关,但是当我得到输出时(所以如果我在调用 atoi 之前调用 printf),它的形式是:(spaces=_--) -- -_4 所以,我说得很好。转换为整数不起作用:/
  • 不,它们不一样。 Windows 样式的文本文件以 2 字符序列 CR 和 LF 结束每一行(C 语法中的'\r''\n')。 Unix 风格的文本文件只使用一个 LF 字符。在 C 中,文本模式 I/O 会根据需要自动将行尾转换为 '\n',因此如果您使用 getcfscanf 进行输入。但是,如果您要处理的是非本地格式的文件,那就更复杂了。
  • push numToRead 推送变量的地址(读取的字节太多!)。你想推送 [contents] - 你必须说“dword”......而且它必须是一个 dword。如果您的讲师说读取 7 个字节,那可能就是您应该做的 - 并确保您的缓冲区有 7 个字节的空间! (将其设为 8 个字节 - 为终止零留出空间)我不确定这是否能解决您使用 atoi 的问题,但这是我看到的第一个问题。 push BUFFERSIZE 是正确的 - 它是一个常数,而不是一个变量。
  • Keith:它使用 ascii CR/LF 按照:asciitable.com 我想我对使用 Windows 样式的意思有点困惑:不使用 0xa 和 0xd *尼克斯格式?弗兰克:根据 fgets 页面:cplusplus.com/reference/cstdio/fgets 它说使用 num 作为要复制到 str 中的最大字符数(包括终止的空字符)。我想阅读所有8个?谢谢两位! :)

标签: linux gcc assembly x86 nasm


【解决方案1】:

除非我在手机上看不到它,但你没有在通话后平衡堆栈。这些 c 函数不是 stdcall ,因此您必须在每次调用后调整堆栈。我愿意:

add esp, 4 * numofpushes 这可能是您的段错误的根源。

【讨论】:

  • 嗨,Gunmer,你说得对,我在调用后没有平衡堆栈。不过这有关系吗?在顶部我保留了我的堆栈指针,在底部返回它——这不是标准操作过程吗?谢谢!
  • (我只是尝试添加 add esp 4*numofpushes, no dice :/ )谢谢!
  • 这有关系吗?是的,这很重要!!!!你的学习大会?一开始就学习正确的方法,以后你会遇到更少的问题。大多数 C 函数不会清理堆栈,你必须这样做!!!而且您确实将 numofpushes 更改为实际数字,对吗?
  • 我确实做到了。我现在只是想用正确的推送来重写整个事情。就推送而言,只要我不更改规范(a32/a16)推送将始终在堆栈顶部放置 4 个字节;对吗?
  • OOOOOHKAY 你是对的。非常感谢您引起我的注意——从现在开始,我将在我的 add esp,4 中很挑剔。
【解决方案2】:

edit:有趣的是,我可以调用 atoi 就好了。那是我尝试的时候

  push eax
  call atoi 
  push eax
  call printf 

我得到分段错误。

来自atoi reference“成功时,函数将转换后的整数作为 int 值返回。”
传递任何随机整数(如4)作为以下printf(即format 字符串指针)的第一个参数不太可能结束。

【讨论】:

  • (目前再次运行我的代码以确保这实际上不是问题。但我真的希望它是!)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-09-20
  • 2013-05-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-06
相关资源
最近更新 更多