NASM - 分段错误和其他问题
这是我在这里发表的第一篇文章。我不确定我的格式是否正确,所以如果我搞砸了,请原谅我。
无论如何,这应该需要两个输入,将一个减半,另一个加倍,然后打印它们。它不应该正常工作,因为输入数据是字符,但输出仍然令人困惑:
[poise] [/home/a/a_mccr/terminal] > ./assignment2
Please enter a four-digit number, negative or positive
1234
The number you entered is
Half the entered value is
ÞH
Double the entered value is
x# ÞH
Segmentation fault
它不会打印出我的输入(即 1234),然后每次输出都是 PH,然后是 X# PH。所有这些都表明输入没有被存储,但我不明白为什么。另外,我在程序结束时遇到了一个神秘的分段错误...救命!这是代码:
segment .data ;to compile use: nasm -f elf assignment2.asm
; ld -o assignment2 assignment2.o
msg1 db 'Please enter a four-digit number, negative or positive', 0xA
len1 equ $-msg1 ;length of 1st message
msg2 db 'The number you entered is', 0xA
len2 equ $-msg2 ;length of 2nd message
msg3 db 'Half the entered value is', 0xA
len3 equ $-msg3 ;length of 3rd message
msg4 db 'Double the entered value is', 0xA
len4 equ $-msg4 ;length of 4th message
segment .bss
input2 resb 3 ;reserve 5 bytes for the entered number
input resb 3 ;reserve 5 bytes for the entered number
segment .text
global _start
_start:
mov eax, 4 ;select kernel call 4, the write function
mov ebx, 1 ;use the default output device (print in terminal)
mov ecx, msg1 ;set the pointer to msg
mov edx, len1 ;set the length to len
int 0x80 ;call write function
mov eax, 3 ;select the kernel read function
mov ebx, 0 ;use the default input device (user txt input)
mov ecx, input ;pointer to input variable
int 0x80 ;invoke kernel read function
mov eax, 4 ;select kernel call 4, the write function
mov ebx, 1 ;use the default output device (print in terminal)
mov ecx, msg2 ;set the pointer to msg2
mov edx, len2 ;set the length to len2
int 0x80 ;call write function
mov eax, 4 ;select kernel call 4, the write function
mov ebx, 1 ;use the default output device (print in terminal)
mov ecx, input ;set the pointer to input
int 0x80 ;call write function
mov eax, [input] ;move input to eax register
mov ebx, [input] ;move input to ebx register
shr eax, 1 ;shift eax 1 place to the right
shl ebx, 1 ;shift ebx 1 place to the left
mov [input], eax ;move contents of eax to input
mov [input2], ebx ;move contents of ebx to input2
mov eax, 4 ;Write message about half
mov ebx, 1 ;use the default output device (print in terminal)
mov ecx, msg3 ;set the pointer to msg3
mov edx, len3 ;set the length to len3
int 0x80 ;call write function
mov eax, 4 ;write contents of input
mov ebx, 1 ;use the default output device (print in terminal)
mov ecx, input ;set the pointer to input
int 0x80 ;call write function
mov eax, 4 ;write message about double
mov ebx, 1 ;use the default output device (print in terminal)
mov ecx, msg4 ;set the pointer to msg4
mov edx, len4 ;set the length to len4
int 0x80 ;call write function
mov eax, 4 ;write contents of input2
mov ebx, 1 ;use the default output device (print in terminal)
mov ecx, input2 ;set the pointer to input2
int 0x80 ;call write function
_exit:
mov eax, 1 ;standard exit
mov ebx, 0 ;0 is normal
int 0x80
this is my first ever post here. I'm not sure if I've done the formatting correctly, so forgive me if I've messed up.
Anyway, this is supposed to take two inputs, halve one and double the other, and then print them. It's not supposed to work properly, as the input data is in characters, but the output is nonetheless confusing:
[poise] [/home/a/a_mccr/terminal] > ./assignment2
Please enter a four-digit number, negative or positive
1234
The number you entered is
Half the entered value is
ÞH
Double the entered value is
x# ÞH
Segmentation fault
It doesn't print out my input (which is 1234), and then every time the output is PH and then X# PH. All this indicates to me that the input is not being stored, but I can't figure out why. Also I get a mysterious segmentation fault at the end of my program... Help! Here's the code:
segment .data ;to compile use: nasm -f elf assignment2.asm
; ld -o assignment2 assignment2.o
msg1 db 'Please enter a four-digit number, negative or positive', 0xA
len1 equ $-msg1 ;length of 1st message
msg2 db 'The number you entered is', 0xA
len2 equ $-msg2 ;length of 2nd message
msg3 db 'Half the entered value is', 0xA
len3 equ $-msg3 ;length of 3rd message
msg4 db 'Double the entered value is', 0xA
len4 equ $-msg4 ;length of 4th message
segment .bss
input2 resb 3 ;reserve 5 bytes for the entered number
input resb 3 ;reserve 5 bytes for the entered number
segment .text
global _start
_start:
mov eax, 4 ;select kernel call 4, the write function
mov ebx, 1 ;use the default output device (print in terminal)
mov ecx, msg1 ;set the pointer to msg
mov edx, len1 ;set the length to len
int 0x80 ;call write function
mov eax, 3 ;select the kernel read function
mov ebx, 0 ;use the default input device (user txt input)
mov ecx, input ;pointer to input variable
int 0x80 ;invoke kernel read function
mov eax, 4 ;select kernel call 4, the write function
mov ebx, 1 ;use the default output device (print in terminal)
mov ecx, msg2 ;set the pointer to msg2
mov edx, len2 ;set the length to len2
int 0x80 ;call write function
mov eax, 4 ;select kernel call 4, the write function
mov ebx, 1 ;use the default output device (print in terminal)
mov ecx, input ;set the pointer to input
int 0x80 ;call write function
mov eax, [input] ;move input to eax register
mov ebx, [input] ;move input to ebx register
shr eax, 1 ;shift eax 1 place to the right
shl ebx, 1 ;shift ebx 1 place to the left
mov [input], eax ;move contents of eax to input
mov [input2], ebx ;move contents of ebx to input2
mov eax, 4 ;Write message about half
mov ebx, 1 ;use the default output device (print in terminal)
mov ecx, msg3 ;set the pointer to msg3
mov edx, len3 ;set the length to len3
int 0x80 ;call write function
mov eax, 4 ;write contents of input
mov ebx, 1 ;use the default output device (print in terminal)
mov ecx, input ;set the pointer to input
int 0x80 ;call write function
mov eax, 4 ;write message about double
mov ebx, 1 ;use the default output device (print in terminal)
mov ecx, msg4 ;set the pointer to msg4
mov edx, len4 ;set the length to len4
int 0x80 ;call write function
mov eax, 4 ;write contents of input2
mov ebx, 1 ;use the default output device (print in terminal)
mov ecx, input2 ;set the pointer to input2
int 0x80 ;call write function
_exit:
mov eax, 1 ;standard exit
mov ebx, 0 ;0 is normal
int 0x80
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
当您读取输入时,您似乎忘记指定要读取的长度:
我假设
edx
的旧值将是read 的长度(2)
——这将远远长于您的输入
空间。 (还有五个字节?当然看起来很奇怪。另外,注释似乎与代码不匹配,但这可能是我的无知而不是你的代码。)When you're reading input, it appears that you forgot to specify a length to read:
I presume that the old value of
edx
will be the length ofread(2)
-- which will be far longer than yourinput
space. (And five bytes? Sure seems odd. Also, the comment doesn't seem to match the code, but that could be my ignorance more than your code.)让我说得对:
在输入和输出之前,您需要将收到的 ASCII 字符串从十进制转换为二进制,然后再转换回来。如果您不使用
atoi()
或类似的,您可以编写自己的版本,实际上并不那么难。您需要为字符串保留更多字节,32 位数字最多可能有 10 个字符长。如果您这样做了,您可能自己已经看到了错误,因为您可能会发现很难将 10 字节字符串压缩到 32 位寄存器中。
Let me get that right:
You need to convert the ASCII string you receive from decimal to binary and back before input and output. If you don't to use
atoi()
or similar, you can write your own version, it isn't actually that hard.You need to reserve more bytes for the strings, a 32 bit number may be up to 10 chars long. Would you have done that, you probably have seen there error by yourself, because you might have find it difficult to squeeze a 10 byte string into a 32 bit register.