我似乎有一个有趣的问题,虽然我可能做了一些明显错误的事情。
我的问题是我试图将AAAABBBBCCCC推入堆栈,然后通过stdout打印它们。但是,似乎在我的x86_64环境中,push 0x41414141
推送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
。
我认为push
指令推送dword
值。到qword
大小的堆栈?我是否正确地想到这一点?
考虑到额外的字节数,并将长度更改为20,可以避免这种情况。但这会导致问题sys_open
。
所以我的问题是,我做错了什么?
答案 0 :(得分:8)
对于64位代码,堆栈(RSP)始终在8字节边界上对齐。也没有“push qword imm64”指令(见注释)。
我的建议是将字符串“AAAABBBBCCCC”存储在数据部分(或“.rodata”)中,而不是乱码。
保留你的变态的替代方案可能是:
sub rsp,16
mov [rsp],'AAAA'
mov [rsp+4],'BBBB'
mov [rsp+8],'CCCC'
....
add rsp,16
注意:AMD的手册说有一个“push imm64”指令。 AMD的手册是错误的 - 该指令实际上推动了32位立即(符号扩展为64位)。