assembly 在x86_64上将值推入堆栈内存时,堆栈内存是如何工作的?

llycmphe  于 2022-12-13  发布在  其他
关注(0)|答案(1)|浏览(101)

我一直在汇编中写一些代码,我发现了一个错误,它覆盖了其他内存位置,并给我一个分段错误,这个麻烦是使用rbp寄存器造成的,但下面的例子使用其他寄存器,使之易于理解。

; Moving some value to rax and pushing to stack
 mov rax, "romulomo"
 push rax

 ; Moving rbp to same location of rsp that points to "romulomo"
 mov rbp, rsp

 ; Moving a debug byte to position rbp-1
 mov BYTE [rbp-1], "#"

 ; Printing everything
 mov rax, 1
 mov rdi, 1
 lea rsi, [rbp]
 mov rdx, 8
 syscall

 ; Exit from program
 mov rax, 60
 syscall

我的疑问是:利用堆栈向下增加的事实,rbp指向使用rax寄存器推入的数据上的序列(0)的第一个字节或序列(7)的最后一个字节?

程序的输出为:

romulomo

这不奇怪吗?我把一个“#”放在应该是“romulo”的第一个“o”的地方,程序打印的正是“romulomo”。
有趣的是,如果我把'#'使用rbp+1像在下面的例子,这没有任何麻烦的工作,然而,这样做,理论上我把之前的整个序列的字节...

mov BYTE [rbp+1], "#"

有人能帮忙吗?

dauxcl2d

dauxcl2d1#

让我们假设RSP指向地址:地址

; Moving some value to rax and pushing to stack
 mov rax, "romulomo" 
 push rax 

;                                      +-> RSP=0xFF1E98-8
;Low              stack                |         High
;+-------------------------------------+--------+
;|                                     |romulomo| 
;+-------------------------------------+--------+
; RSP=0xFF1E90 | RBP=0xXXXXXXX
 

; Moving rbp to same location of rsp that points to "romulomo"
 mov rbp, rsp

; RSP=0xFF1E90 | RBP=0xFF1E90
 
; Moving a debug byte to position rbp-1
 mov BYTE [rbp-1], "#"

;                                       +-> RBP = RSP = 0xFF1E90
;Low              stack           |RBP-1|         High
;+--------------------------------+-----+--------+
;|                                |  #  |romulomo| 
;+--------------------------------+-----+--------+
; RSP=0xFF1E90 | RBP=0xFF1E90

; mov BYTE [rbp+1], "#" ; to replace the first "o" with "#": r#mulomo

;                                         
;Low              stack           |RBP-1|RBP|RBP+1|      RBP+8
;+--------------------------------+-----+---+-----+------+
;|                                |  #  | r |  o  |mulomo| 
;+--------------------------------+-----+---+-----+------+

 ; Printing everything
 mov rax, 1          ; __NR_write
 mov rdi, 1          ; fd = stdout

 lea rsi, [rbp]      ; mov rsi, rbp  would be more efficient
;            RSI = start of buffer = RBP = RSP = 0xFF1E90
;Low              stack           |RBP-1|         High
;+--------------------------------+-----+--------+
;|                                |  #  |romulomo| 
;+--------------------------------+-----+--------+

 mov rdx, 8          ; length = 8 bytes
 syscall             ; write(1, rsi, 8)

 ; Exit from program
 mov rax, 60
 syscall

相关问题