提问人:cMard 提问时间:11/18/2023 更新时间:11/18/2023 访问量:48
组装:分段故障原因
Assembly: cause of segmentation fault
问:
我是新手,所以我没有那么多知识。我只是想从用户那里读取一些,然后输出,然后输出用户输入的内容。assembly language
message
"Hello, World!\n"
message
这是我基本上要做的:
# TODO: Read message from input, output "Hello, World!", and output message on newline
.section .data # Data that will be used by program
## * CONSTANTS * ##
.equ LINUX_SYSCALL, 0x80 # Interrupt ID to make syscall on kernel (GNU/Linux)
## * SYCALL IDs * ##
.equ EXIT_SYS, 1 # SYSCALL Number for exiting
.equ OPEN_SYS, 5 # SYSCALL Number for opening files
.equ READ_SYS, 3 # SYSCALL Number for reading from files
.equ WRITE_SYS, 4 # SYSCALL Number for writing to files
.equ CLOSE, 6 # SYSCALL Number to close files
## * File modes * ##
.equ READ_MODE, 0 # Reading mode for files
.equ WRITE_MODE, 03101 # Writing mode for files
## * File permissions * ##
.equ DEFAULT_PERMISSION, 0666 # Default permission to interact with files
## * Default file descriptors * ##
.equ STDIN, 0 # Default GNU/Linux input file
.equ STDOUT, 1 # Default GNU/Linux output file
.equ STDERR, 2 # Default GNU/Linux error-log file
## * Constant variables * ##
OUTPUT_MSG: # "Hello, World!" message
.ascii "Hello, World!\n"
SIZE_OF_MSG: # Size of "Hello, World!"
.long 14 # remember to count '\n' as 1 byte
.section .bss # Reserved memory area
.equ BUFFER_SIZE, 500 # Size of buffer that will be read from STDIN
.lcomm BUFFER, 500 # Buffer that will be read from STDIN
.section .text # Code area
.globl _start # Starting function definiton
# @brief: Label to terminate program successfuly
_exit_success:
movl $EXIT_SYS, %eax
movl $0, %ebx
int $LINUX_SYSCALL
# @brief: Label to output `message` that stored in `%ecx`
# @param: `%ecx` must have `message` to output
# @param: `%edx` must have size of `message`
_output_msg:
movl $WRITE_SYS, %eax
movl $STDOUT, %ebx
int $LINUX_SYSCALL
ret
# @brief: Label to get input `buffer` from STDIN
# @param: `%ecx` must have `buffer` to store data
# @param: `%edx` must have size of `buffer` which will be used for data
_read_msg:
movl $READ_SYS, %eax
movl $STDIN, %ebx
int $LINUX_SYSCALL
ret
# @brief: Label to get size of a `buffer`
# @param: `%eax` must have pointer to `buffer`'s first char
# @return: size of buffer will be stored in `%edx`
_get_buffer_size:
movl $0, %edx
jmp .start_buffer_size
ret
.start_buffer_size:
incl %eax
incl %edx
cmpl $0, (%eax)
jnz .start_buffer_size
ret
# @brief: _start function to start program
_start:
## * Get input message * ##
movl $BUFFER, %ecx
movl $BUFFER_SIZE, %edx
call _read_msg
## * Output constant message * ##
movl $OUTPUT_MSG, %ecx # Store message in %ecx parameter
movl $SIZE_OF_MSG, %edx # Store size of message in %edx parameter
call _output_msg # Output the constant message
## * Output message that was read * ##
movl $BUFFER, %ecx
call _get_buffer_size
call _output_msg
jmp _exit_success # Terminate program
_exit_success:
这个只是终止程序。是 1,并且是 。EXITSYS
LINUX_SYSCALL
0x80
_output_msg:
此标签输出存储在 中的消息,其大小必须在寄存器上。这里是 4 和 1%ecx
%edx
WRITE_SYS
STDOUT
_read_msg:
此标签从(即 0)获取输入。必须存储在 并且保留的大小必须为 onSTDIN
BUFFER
%ecx
BUFFER
%edx
_get_buffer_size:
这里必须是 的第一个字符,输出 (大小 ) 将开启%eax
BUFFER
BUFFER
%edx
我知道不是这样使用的,但是with的方法对我来说很复杂,所以我尝试了自己的方法(是的,它只是存储和in)。functions
assembly
stack
parameters
return value
registers
我认为问题出在,因为错误表明程序访问(或尝试访问)不存在或不允许我们访问(或尝试访问)的内存地址。_get_buffer_size
segmentation fault
答: 暂无答案
评论
_get_buffer_size
strlen
cmpb
cmpl
read
read