【发布时间】:2013-03-05 17:34:29
【问题描述】:
对于我的项目工作,我测试了一个代码 sn-p。我发现这段代码sn-p由于使用堆栈而出现分段错误。但是,我必须使用堆栈来解决它。谁能帮我找到出了问题?我的程序将显示字符串变量的第二个字符。我的代码 sn-p 如下:
section.data
string db "test",10,0
msg2 db "%c",10,0
main:
xor eax,eax
mov eax, string
mov ebx,1 ; suppose I want to get the second character of string. SO I store the index of that character in ebx
pusha
push eax
push ebx
add esp,8
popa
pop dword[ebx] ; **I assume that this following 3 lines arise segmentation fault**
pop eax ;
mov bl,[eax+ebx] ; I want to move the fisrt character to BL using the index value stored in ebx which i popped just.
pusha
push ebx
call putchar
add esp,4
popa
pusha
push msg2
call printf
add esp,4
popa
在这里,为了您的善意,我想明确说明这段代码 sn-p 的目的是了解如何操作堆栈。
在这里,@nrz 最近给了我以下代码的想法,我在这里编辑了上面的代码:
section.data
string db "test",10,0
msg2 db "%c",10,0
main:
xor eax,eax
mov eax, string
mov ebx,1 ; suppose I want to get the second character of string. SO I store the index of that character in ebx
mov eax,string
movzx eax,byte [eax]
push eax ; these push and pop are for solving it using the stack,
pop ebx
pusha
push ebx
call putchar
add esp,4
popa
pusha
push msg2
call printf
add esp,4
popa
我的查询具体是:
我会给出索引值。它应该在
ebx寄存器中吗?最重要的是,我使用堆栈的主要想法是使用我之前推入
ebx的索引值来访问string变量的每个字符。 [这是强制性的。有可能吗?]-
我也想将输出存储在一个 8 位寄存器中。
所以我的全部想法是这样的:
mov al, [string+ebx] ;is it possible?我必须从堆栈中取出
ebx的值。我将在ebx中输入一个值,然后在push ebx中输入一个值,在mov al,[string+ebx]时,我将在pop ebx中获取mov指令的值。说明更有可能是这样的:pop ebx mov al,[string+dword[ebx]] ;which is a wrong statement shown by NASM
我热切期待您的回复。
谢谢,
【问题讨论】:
-
push ebx在call putchar之前推送的值是ASCII 码,不是任何类型的索引或内存地址。通常,使用该值不可能“访问字符串的每个字符”。大致有两种打印方式:1. 循环遍历字符串,并在当时打印它的字符(例如,使用call putchar,如您的代码中所示),或 2. 一次打印完整的字符串,使用 @ 987654337@ 或 Linux APIwrite函数 (4)。但是如果字符串长度被预先确定为 4 个字节,比如test,这是可能的。字符串长度总是4字节吗? -
mov al, [string+ebx]肯定是一个可能的指令,但 它不使用堆栈,如果这是要求的话。请参阅我编辑的“正常”mov al, [string+ebx]代码和“使用堆栈”代码的答案:push dword [ebx+string]、and dword [esp], 0x000000ff、pop eax。 -
@nrz:我不知道,我该如何向你表达我的感激之情,并表示我的遗憾,可能是我的英语知识不足并没有帮助你理解我的想法。我对此表示歉意。我提到我必须从堆栈中获取 ebx 的值。我将在 ebx 中输入一个值,然后 PUSH THE EBX 并在 mov al,[string+ebx] 时弹出 ebx 以获取 mov 指令的值。更有可能是 mov al,[string+dword[ebx]](这是 NASM 显示的错误语句)。但是在您的代码中,没有办法弹出 ebx 的值来执行“string”
-
如果你不以任何方式处理堆栈,除了
push和pop指令,push eax、push ebx、add esp,8是绝对没有必要的。它所做的只是先推送eax,然后推送ebx,然后将esp恢复为原始值。所以和push eax,push ebx,pop ebx,pop eax是一样的;最后所有涉及的寄存器(eax,ebx,esp)都有它们的原始值。 -
是的,那是因为您的堆栈不平衡:
push eax、push ebx、add esp,8、pop ebx、pop eax。每个push减去esp4,每个pop加4 到esp,然后用add esp,8再加8 到esp,导致堆栈不平衡。此外,整个push eax、push ebx、add esp,8、pop ebx、pop eax块是完全没有必要的。你应该把它关掉,因为它没有任何作用(除了作为一个非常基本的代码混淆)。如果您想使用push和pop指令,无论如何都要保持堆栈平衡,否则很可能会出现分段错误。
标签: linux assembly x86 stack nasm