我试图打印一个数组,反转它,然后再打印一次。我设法打印了一次。我也可以连续两次调用 _printy,它也能工作。但是代码被 _reverse 函数中断。它没有分段错误,退出代码24(我在网上查了一下,但这似乎意味着已经超过了文件描述符的最大数量,我不能理解这在这个上下文中的含义)。我使用了调试器,循环逻辑似乎是有意义的。
我没有在RDI中传递数组,因为 _printy 在退出时会恢复该寄存器的内容。我还尝试在调用 _reverse 之前将其直接加载到RDI中,但这并不能解决问题。
我不知道出了什么问题。你知道吗?
BITS 64
DEFAULT REL
; -------------------------------------
; -------------------------------------
; PRINT LIST
; -------------------------------------
; -------------------------------------
%define SYS_WRITE 0x02000004
%define SYS_EXIT 0x02000001
%define SYS_OPEN 0x02000005
%define SYS_CLOSE 0x02000006
%define SYS_READ 0x02000003
%define EXIT_SUCCESS 0
%define STDOUT 1
%define LF 10
%define INT_OFFSET 48
section .text
extern _printf
extern _puts
extern _exit
global _main
_main:
push rbp
lea rdi, [rel array]
call _printy
call _reverse
call _printy
pop rbp
call _exit
_reverse:
push rbp
lea rsi, [rdi + 4 * (length - 1) ]
.LOOP2:
cmp rdi, rsi
jge .DONE2
mov r8, [rdi]
mov r9, [rsi]
mov [rdi], r9
mov [rsi], r8
add rdi,4
sub rsi,4
jmp .LOOP2
.DONE2:
xor rax, rax
lea rdi, [rel array]
pop rbp
ret
_printy:
push rbp
xor rcx, rcx
mov r8, rdi
.loop:
cmp rcx, length
jge .done
push rcx
push r8
lea rdi, [rel msg]
mov rsi, [r8 + rcx * 4]
xor rax, rax
call _printf
pop r8
pop rcx
add rcx, 1
jmp .loop
.done:
xor rax, rax
lea rdi, [rel array]
pop rbp
ret
section .data
array: dd 78, 2, 3, 4, 5, 6
length: equ ($ - array) / 4
msg: db "%d => ", 0
使用调试器中的一些信息进行编辑
单步执行 _printy 函数时,一旦到达_printf
调用,将发出以下消息。
* thread #1, queue = 'com.apple.main-thread', stop reason = step over failed (Could not create return address breakpoint.)
frame #0: 0x0000000100003f8e a.out`printf
a.out`printf:
-> 0x100003f8e <+0>: jmp qword ptr [rip + 0x4074] ; (void *)0x00007ff80258ef0b: printf
0x100003f94: lea r11, [rip + 0x4075] ; _dyld_private
0x100003f9b: push r11
0x100003f9d: jmp qword ptr [rip + 0x5d] ; (void *)0x00007ff843eeb520: dyld_stub_binder
我不是Maven,但在网上快速研究后得出以下结论
在执行“thread step-out”命令期间,检查我们将要放置断点的内存是否可执行。以前,如果当前函数具有非标准堆栈布局/ABI,并且在返回地址通常所在的位置具有有效的数据指针,写入断点时将发生数据损坏。这可能导致错误报告的崩溃或程序状态的无提示损坏。现在,如果上述检查失败,命令将安全地中止。
因此,这毕竟不是问题(我也能够跟踪printf
调用的执行)。但这确实是我能够从调试器中提取的唯一可理解的信息。在一些相当晦涩(对我来说)的函数调用中,我深入了解到这一点
* thread #1, queue = 'com.apple.main-thread', stop reason = instruction step into
frame #0: 0x00007ff80256db7f libsystem_c.dylib`flockfile + 10
libsystem_c.dylib`flockfile:
-> 0x7ff80256db7f <+10>: call 0x7ff8025dd480 ; symbol stub for: __error
0x7ff80256db84 <+15>: mov r14d, dword ptr [rax]
0x7ff80256db87 <+18>: mov rdi, qword ptr [rbx + 0x68]
0x7ff80256db8b <+22>: add rdi, 0x8
Target 0: (a.out) stopped.
(lldb)
Process 61913 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = instruction step into
frame #0: 0x00007ff8025dd480 libsystem_c.dylib`__error
这是_printf
中发生的函数调用之一。
如果我还能做些什么,请再问一些问题。
1条答案
按热度按时间lnlaulya1#
您的数组由
int32
数字组成,在nasm术语中也称为dd
,但您的交换操作在64位数字上:假设您没有进行一些疯狂的优化,即同时交换一对元素,您希望它保持为32位: