nasm 64 位推送 qword? [英] nasm 64 bit push qword?
问题描述
我似乎有一个有趣的问题,尽管我可能做错了什么.
I seem to have an interesting issue, though I am probably doing something blatantly wrong.
我的问题是我试图将 AAAABBBBCCCC 推入堆栈,然后通过标准输出打印它们.然而,在我的 x86_64 环境中,push 0x41414141
似乎推送了 4141414100000000
.
My issue is that I am attempting to push AAAABBBBCCCC onto the stack, then print them through stdout. However it seems that in my x86_64 environment the push 0x41414141
pushes 4141414100000000
.
所以下面的代码块:
global _start
section .text
_start:
push 0x43434343 ; CCCC
push 0x42424242 ; BBBB
push 0x41414141 ; AAAA
xor rax,rax ; Zero RAX
mov byte al,0x1 ; 1 for sys_write
mov rdi,rax ; 1 for stdout
mov rsi,rsp ; RSP for source
mov byte dl,0xC ; 12
syscall
xor rax,rax ; Zero RAX
mov al, 0x3C ; 60 for sys_edxit
cdq ; 0 for clean exit.
syscall
输出 AAAABBBB
,我以为只有 8 个字节,实际上是我要求的 12 个.当通过管道传输到输出文件并在 hexedit 中查看时,我注意到它显示 414141410000000042424242
.
Outputs AAAABBBB
, of what I thought was only 8 bytes, was actually the 12 I asked for. When piped to an output file and looked at in hexedit, I noticed it was displaying 414141410000000042424242
.
我认为 push
指令会推送一个 dword
值.到 qword
大小的堆栈上?我的想法正确吗?
I figure the push
instruction pushes a dword
value. onto a qword
sized stack? Am I correct in thinking this?
考虑到额外的字节,并将我的长度更改为 20,可以很好地避免这种情况.但这会导致 sys_open
之类的问题.
This can be cheeply avoided by taking into account the extra bytes, and changing my length to 20. But that would cause issues with things like sys_open
.
所以我的问题是,我做错了什么?
So my question is, what am I doing wrong?
推荐答案
对于 64 位代码,堆栈 (RSP) 始终在 8 字节边界上对齐.也没有push qword imm64".说明(见注释).
For 64-bit code the stack (RSP) is always aligned on an 8 byte boundary. There's also no "push qword imm64" instruction (see note).
我的建议是存储字符串AAAABBBBCCCC";在它所属的数据部分(或.rodata")中,而不是弄乱堆栈.或者在shellcode中,
My advice would be to store the string "AAAABBBBCCCC" in your data section (or ".rodata") where it belongs instead of messing with the stack. Or in shellcode,
push 'CCCC' ; push qword, including 4 bytes of zeros
mov rax, 'AAAABBBB' ; mov reg, imm64; pick any register
push rax ; push qword
保留你变态的另一种选择可能是:
An alternative that preserves your perversion might be:
sub rsp,16
mov dword [rsp],'AAAA'
mov dword [rsp+4],'BBBB'
mov dword [rsp+8],'CCCC'
....
add rsp,16
注意:AMD 的手册说有一个push imm64"操作说明.AMD 的手册是错误的 - 该指令实际上是推送 32 位立即数(带符号扩展到 64 位).
Intel 的手册没有这个问题:https://www.felixcloutier.com/x86/推
还相关:当我不指定操作数大小时,push指令将多少字节推入堆栈? - 你绝对不能在 64 位模式下进行双字推入.
Intel's manual doesn't have that problem: https://www.felixcloutier.com/x86/push
Also related: How many bytes does the push instruction push onto the stack when I don't specify the operand size? - you definitely can't do a dword push in 64-bit mode.
这篇关于nasm 64 位推送 qword?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!