【发布时间】:2021-11-26 08:34:46
【问题描述】:
代码:
;The value you want to print must be in the eax register
;one 32-byte resb to hold bit value
;and must be newline db
printDD_start:
push ebx
push ecx
push edx
push esi
push esp
mov esi,0
printDD:
cmp esi,31
jg printDD_printStart
test eax,1
jz printDD_zero
jmp printDD_one
printDD_zero:
mov dword [printDD_var_save + esi],48
inc esi
shr eax,1
jmp printDD
printDD_one:
mov dword [printDD_var_save + esi],49
inc esi
shr eax,1
jmp printDD
printDD_printStart:
mov esi,31
printDD_print:
cmp esi,0
jl printDD_exit
mov esp,printDD_var_save
add esp,esi
mov eax,4
mov ebx,1
mov ecx,esp
mov edx,1
int 80h
dec esi
jmp printDD_print
printDD_exit:
mov eax,4
mov ebx,1
mov ecx,newline
mov edx,1
int 80h
pop ebx
pop ecx
pop edx
pop esi
pop esp
ret
我正在将一个 4 字节变量的位打印到屏幕上。程序正在运行。它正确打印 EAX 寄存器中的值,但我得到了最新的分段错误错误。
【问题讨论】:
-
哪条指令出错了?当您在 GDB 下运行它时,寄存器中的值是什么?不要只用
...填写您的问题,直到它允许您发布,实际上在您的minimal reproducible example 中包含调试详细信息。 -
等一下,
pop esp??这只是编写mov esp, [esp]的一种简洁方式,在这里没有任何意义。此外,您没有以与推送相反的顺序弹出。 -
我没有找到与推送不匹配的流行音乐的规范副本。无论如何,如果您没有尝试在堆栈本身上保存/恢复堆栈指针(这是没有意义的),那么您不匹配的推送/弹出顺序只会打乱调用者的寄存器值,而不是让 ESP 指向错误的位置,不是退货地址。 (这可能是正在发生的事情,除非还有其他错误。)
-
@Peter Cordes:
mov esp,printDD_var_save和add esp,esi也很可疑。 -
您似乎在尝试将
esp用作计算中的通用寄存器。别。在大多数指令接受它作为操作数的意义上,它在架构上是一个“通用寄存器”,但它仍然是堆栈指针,任意修改它会弄乱堆栈。如果您需要另一个寄存器,看起来edi和ebp可用。
标签: assembly segmentation-fault nasm