对于我的项目工作,我测试了一段代码片段。我发现由于堆栈的使用,此代码段出现了分段错误。但是,我必须使用堆栈解决它。任何人都可以帮我找出问题?我的程序将显示字符串变量的第二个字符。我的代码片段如下:
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
在此,为了您的善意考虑,我想明确指出,此代码段的目的是了解如何操作堆栈。
在这里,@ 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
寄存器中吗?
最重要的是,我使用堆栈的主要思想是使用我之前在string
中推送的索引值来处理ebx
变量的每个字符。 [这是强制性的。有可能吗?]
我想将输出存储在一个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
我急切地等待你的回应。
感谢你,
答案 0 :(得分:0)
代码中存在一些错误和不必要的指示:
mov eax, string ; this line makes eax point to string, but... xor eax,eax ; this line zeroes eax immediately. delete this line. mov ebx,1 ; this line is unnecessary, but does not cause problems. pusha ; unnecessary. push eax ; unnecessary. push ebx ; unnecessary. add esp,8 ; unnecessary. popa ; unnecessary. pop dword[ebx] ; [1] = [esp], esp = esp+4, probably causes segmentation fault. pop eax ; eax = [esp], esp = esp+4 mov bl,[eax+ebx]
编辑:打印所有字符,只需遍历字符串:
section.data string db "test",10 string_length equ $-string ; number of characters in the string. ; no zero needed in the end of the string. msg2 db "%c",10,0 main: xor eax,eax ; eax is the index to the string. char_loop: push dword [eax+string] ; push 4 first characters into stack. and dword [esp], 0x000000ff ; x86 is little-endian, so 1st character ; is the lowest byte. pop ebx ; pop the ASCII code of the character into ebx. pushad push ebx call putchar add esp,4 popad inc eax cmp eax,string_length jb char_loop
修改:使用ebx
作为索引来匹配问题中的更改的新代码。
section.data string db "test",10 string_length equ $-string ; number of characters in the string. ; no zero needed in the end of the string. msg2 db "%c",10,0 main: xor eax,eax ; zero eax, for putchar. xor ebx,ebx ; ebx is the index to the string. char_loop: ;push dword [ebx+string] ; push 4 first characters into stack. ;and dword [esp], 0x000000ff ; x86 is little-endian, so 1st character ; ; is the lowest byte. ;pop eax ; pop the ASCII code of the character into ebx. mov al,[ebx+string] ; this is the normal way to do it. ; the above 3 instructions do it "using stack", ; as requested in the question. pushad push eax call putchar add esp,4 popad inc ebx cmp ebx,string_length jb char_loop