我正在尝试学习一些非常基本的 ASM,以帮助我阅读 gdb 输出找出东西。我一直在网上关注一些教程,并且遇到了一些我不知道该怎么做的事情。
我正在关注的教程(http://programminggroundup.blogspot.fr/2007/01/programming-from-ground-up.html)在第 5 章中讨论了字符串 IO。它使用 .bss 段来声明 500 长度输入的数组。我可以让它工作没有问题。但是,我现在试图将数组放在堆栈上,而不是放在 .bss 段中(这对我来说似乎是“全局内存”)。
问题是,我无法弄清楚我做错了什么。据我在这里看到的,我已经在堆栈上移动了一个 64 字节的部分,我试图用它来保存输入,然后输出它。该代码没有核心或以其他方式展开,但是当我运行它并键入“Hello”(不带引号)时,结果是“ello”,写在下一个命令行中。它后面是一个换行符,因此在程序终止时立即执行“hello”。
user_omitted@serveromitted:~/folderomitted>./basic_io
Hello
user_omitted@serveromitted:~/folderomitted>ello
据我在这里看到的,我正在写入堆栈。我希望我不需要将其归零,因为输入应该正确覆盖内容。我在这里做错了什么?
这是使用带有气体的 unix IA-64 系统。此外,如果我正在做一些非常愚蠢的事情(不仅仅是与我遇到的问题有关),请告诉我!
.section .text
.globl _start
_start:
pushq %rbp # Store the original base pointer on the stack
mov %rsp, %rbp # The new base pointer is targeting the start of the stack
sub $64, %rsp # Move the stack pointer down by 64 bytes, thus saying we have 64 bytes to play with
mov %rsp, %rcx # Pass the content of the stack pointer to rcx, for the system call
mov $64, %rdx # Store the length of the buffer
mov $3, %rax # State that we want to use system_read
mov $0, %rbx # Select the handler (STDIN)
int $0x80 # invoke
mov $4, %rax # system_write
mov $1, %rbx # STDOUT
mov $64, %rdx # length of buffer
mov %rsp, %rcx # location of the buffer on the stack
int $0x80 # invoke
mov %rbp, %rsp # Restore the stack pointer to the original location
popq %rbp # pop the base pointer off the stack
mov $1, %rax # sys_exit
mov $0, %rbx # return code
int $0x80 # invoke