【发布时间】:2021-01-31 20:15:45
【问题描述】:
我在 NASM x86 中编写了以下程序,但是当我尝试运行它时似乎得到的只是段错误(尝试打印时)和停止打印时的无限循环。代码成功调用printNumber一次,然后出现段错误;因此,我被引导相信这是在循环的第二次迭代中发生的事情。我在这里想念什么?我已将 cmets 添加到我的源代码中以解释发生了什么,但我不明白为什么这会为应该是一个简单程序的程序抛出段错误(目前无法访问 valgrind 或 gdb)。
这是输出:
0Segmentation fault: 11
..这是我写的小程序。我在这里没有看到什么?
SECTION .data
arraylen dd 10
num db 0
farewell: db "Blah"
SECTION .bss
array resq 8
SECTION .text
global start
start:
call fillArr
mov rax, 0x02000001
mov rdi, 0
syscall
printNum:
mov rsi, num
mov rdx, 2
call print
ret
fillArr:
lea rsi, [rel array] ; needed for 64 bit on mac
xor rcx, rcx ; make this 0
arrayloop:
mov [rsi+rcx*8], rcx ; array element rcx updated with value
mov rbx, [rsi + rcx*8] ; grab value at index we just filled
add rbx, 48 ; now offset number by 48 to make it ascii'able
mov [rsi+rcx*8], rbx ; overwritten the value we saw as it's ascii
mov [rel num], rbx ; update storage var
call printNum ; print
inc rcx ; we don't need this anymore
cmp rcx, 4
jne arrayloop
mov rsi, farewell
mov rdx, 4
call print
ret
print:
mov rax, 0x02000004
mov rdi, 1
syscall
ret
【问题讨论】:
-
涉及什么操作系统?
rax=0x2000004应该做什么操作? -
macOS,64 位。我使用以下命令编译它: nasm -f macho64 arr.asm ld -macosx_version_min 10.7.0 -lSystem -o arrayTest arr.o 该操作相当于Linux上的sys call 4(so print)
-
我会一步一步地在调试器(如
lldb)中运行它,但只看代码我担心的是syscall(指令本身)破坏了RCX和R11。您不使用 R11,但您的代码似乎确实依赖于 RCX,而不会在函数fillArr中被破坏。您可以尝试通过保存(即:PUSH RCX)并在返回之前恢复它(即:POP RCX)来保留函数print中的RCX -
@wallyk:它从一开始就被标记为 MacOS。像这样的电话号码是 MacOS 用于“正常”POSIX 系统调用(如
read和write)的电话号码。当然,好的源代码会注释每个syscall确切的系统调用。 -
@PeterCordes:我误读了
macos,以为是macros!
标签: macos assembly segmentation-fault x86-64 nasm