0

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

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

我的查询具体是:

  1. 我将给出索引值。它应该在ebx注册表中吗?

  2. 最重要的是,我使用堆栈的主要想法是使用string我之前推入的索引值来访问变量的每个字符ebx。[这是强制性的。可能吗?]

  3. 我也想将输出存储在一个 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
    

我热切地等待着你的回应。

谢谢你,

4

1 回答 1

0

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

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

普萨;不必要。
推动 eax ; 不必要。
推 ebx ; 不必要。
添加 esp,8 ; 不必要。
波帕;不必要。

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

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

部分数据
  字符串数据库“测试”,10
  string_length equ $-string ; 字符串中的字符数。
                             ; 字符串末尾不需要零。
  msg2 数据库 "%c",10,0
主要的:
    xor eax,eax ; eax 是字符串的索引。

字符循环:
    push dword [eax+string] ; 将 4 个第一个字符推入堆栈。
    和 dword [esp], 0x000000ff ; x86 是 little-endian,所以第一个字符
                                 ; 是最低字节。
    流行 ebx ; 将字符的 ASCII 码弹出到 ebx 中。

    普萨德
    推 ebx
    调用 putchar
    添加 esp,4
    波帕德

    公司
    cmp eax,string_length
    jb char_loop

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

部分数据
  字符串数据库“测试”,10
  string_length equ $-string ; 字符串中的字符数。
                             ; 字符串末尾不需要零。
  msg2 数据库 "%c",10,0
主要的:
    xor eax,eax ; 零 eax,用于 putchar。
    异或 ebx,ebx ; ebx 是字符串的索引。

字符循环:
    ;push dword [ebx+string] ; 将 4 个第一个字符推入堆栈。
    ; 和 dword [esp], 0x000000ff ; x86 是 little-endian,所以第一个字符
    ; ; 是最低字节。
    ;pop eax ; 将字符的 ASCII 码弹出到 ebx 中。

    mov al,[ebx+string] ; 这是正常的做法。
                                  ; 以上3条指令“使用堆栈”,
                                  ; 按照问题的要求。
    普萨德
    推入
    调用 putchar
    添加 esp,4
    波帕德

    公司 ebx
    cmp ebx,string_length
    jb char_loop
于 2013-03-17T08:39:02.347 回答