从非 x4 地址访问堆栈 - 这可能吗?

Accessing the stack from non x4 addresses - is it possible?

好吧,这可能是一个愚蠢的问题,但我想我和其他人可能会在这个过程中学到:

我正在使用 32 位汇编程序和 at&t 语法。

假设我想动态生成一个字符串,将其内容保存到堆栈中:

.data 
str: .long 0
string: .string "value is %s.\n"
.globl main

movb [=10=],str+3 #terminate the string
movb ,str+2
movb ,str+1
pushl $str
movl %esp,%eax
incl %eax
push (%eax)
push $string
call printf
addl ,%esp
ret

它不起作用,我得到一个分段错误。但是,如果我评论行

# incl %eax

并在 str 的开头添加另一个字节:

movb ,str

然后完美运行,显示CCC。

我似乎无法引用从不是 4 的倍数的地址开始的字符串。还是我错了?我知道我可以从任何地址引用变量,但是有没有办法用堆栈来实现?

可以,但是你做错了。您将字符串的地址放在堆栈上,然后尝试递增地址的地址,并取消引用它。你想增加地址。使用 incl (%eax) 增加堆栈上的地址应该有效。然而整个事情过于复杂,你可以简单地做 push $str+1:

movb [=10=],str+3 #terminate the string
movb ,str+2
movb ,str+1
pushl $str+1
push $string
call printf
addl ,%esp
ret

您可以访问未对齐的堆栈,但您应该确保它有意义。因为你在堆栈上有一个 4 字节的地址,如果你访问那个未对齐的地址,你将得到它的 3 个字节,以及来自堆栈上后续项目的另一个字节,无论它是什么。这当然不太可能是有效地址,因此会出现段错误。错误不是访问未对齐的堆栈,而是因为您解除了对无效指针的引用。