对于我的项目工作,我已经测试了一个代码片段。我发现由于使用堆栈,此代码段出现了分段错误。但是,我必须使用堆栈来解决它。谁能帮我找出问题所在?我的程序将显示字符串变量的第二个字符。我的代码段如下:

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



我热切等待您的回复。

谢谢,

最佳答案

代码中有一些错误和不必要的说明:

mov eax,string;这条线使eax指向字符串,但是...
xor eax,eax;这条线立即将eax清零。删除此行。
mov ebx,1;此行是不必要的,但不会引起问题。

普沙;不必要。
推e;不必要。
推ebx;不必要。
加esp,8;不必要。
波帕;不必要。

pop dword [ebx]; [1] = [esp],esp = esp + 4,可能导致分段错误。
流行流行; eax = [esp],esp = esp + 4
mov bl,[eax + ebx]


编辑:要打印所有字符,只需遍历字符串:

段数据
  字符串db“ test”,10
  string_length equ $ -string;字符串中的字符数。
                             ;字符串末尾不需要零。
  msg2 db“%c”,10,0
主要:
    xor eax,eax; eax是字符串的索引。

char_loop:
    push dword [eax + string];将前四个字符压入堆栈。
    和dword [esp],0x000000ff; x86是little-endian,因此第一个字符
                                 ;是最低字节。
    流行ebx;将字符的ASCII代码弹出到ebx中。

    Pushad
    推ebx
    致电putchar
    加esp,4
    波帕德

    公司
    cmp eax,string_length
    jb char_loop


编辑:使用ebx作为索引,以匹配问题中的更改的新代码。

段数据
  字符串db“ test”,10
  string_length equ $ -string;字符串中的字符数。
                             ;字符串末尾不需要零。
  msg2 db“%c”,10,0
主要:
    xor eax,eax;零eax,用于putchar。
    xor ebx,ebx; ebx是字符串的索引。

char_loop:
    ; push dword [ebx + string];将前四个字符压入堆栈。
    ; and dword [esp],0x000000ff; x86是little-endian,因此第一个字符
    ; ;是最低字节。
    ; pop eax;将字符的ASCII代码弹出到ebx中。

    mov al,[ebx + string];这是正常的做法。
                                  ;以上3条指令是“使用堆栈”完成的,
                                  ;根据问题的要求。
    Pushad
    推e
    致电putchar
    加esp,4
    波帕德

    Inc ebx
    cmp ebx,字符串长度
    jb char_loop

关于linux - 如何在Ubuntu11.04中使用NASM维护堆栈,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15458914/

10-13 02:49