从字符串文字中检索单词?

时间:2013-04-27 13:23:25

标签: assembly x86 nasm

在NASM中,我有strconst_0 dw 5, 0, __utf16__('hello')(单个反引号)作为字符串

我正试图像这样访问'h'(其中[ebp + 8]为0而[ebp + 4]是字符串的地址)

mov eax, [ebp+8] ; get the index
mov ebx, [ebp+4] ; get the address
movzx eax, word [ebx + 2 * eax + 4]
push eax
call print_char ; call the print function

但是,当我运行此代码时,只打印一个空字符

编辑:完整列表

main:
pop edx
push ebp
mov ebp, esp
sub esp, 4
mov [ebp-4], edx
mov eax, strconst_0
push eax
push dword 0
call getChar
add esp, 8
push eax
call printChar
add esp, 4
mov edx, [ebp-4]
add esp, 4
pop ebp
push edx
ret

getChar:
pop edx
push ebp
mov ebp, esp
sub esp, 4
mov [ebp-4], edx
mov eax, [ebp+8]
mov ebx, [ebp+4]
movzx eax, word [ebx + 2 * eax + 4]
push eax
pop eax
mov edx, [ebp-4]
add esp, 4
pop ebp
push edx
ret

2 个答案:

答案 0 :(得分:1)

我的论点是错误的。如果我在初始mov指令中交换ebx和eax,它可以正常工作。

答案 1 :(得分:0)

  1. 你在程序开始时将main的返回地址弹出到edx中,这没有任何意义。
  2. 你根本没有任何评论,所以我无法理解你想要做什么,因为你的getChar没有原型。
  3. 基本上,这里的分析,我没有工具,所以我做了一些假设

    main:
        ; why is return address of main popped into edx?
        pop        edx
    
        ; standard stack setup                   
        push       ebp
        mov        ebp,      esp
    
        ; make space for 4 bytes
        sub        esp,      4
    
        ; store edx in where return address used to be... why?
        mov        [ebp-4],  edx
    
        ; move address of strconst_0 to eax
        mov        eax,      strconst_0
    
        ; push eax on stack
        push       eax
    
        ; push 4 bytes 0x00000000 on stack
        push dword 0
    
        ; call getchar(0, strconst_0)
        call       getChar
    
        ; restore stack
        add        esp,      8
    
        ; push eax which was mutated in getChar on stack
        push       eax
    
        ; printChar(eax)
        call       printChar
    
        ; restore stack
        add        esp,      4
    
        ; move whatever we overwritten old return address to, to edx
        mov        edx,      [ebp-4]
    
        ; restore stack
        add        esp,      4
        pop        ebp
    
        ; restore return address
        push       edx
    
        ; return
        ret
    
    ; what do I accept(on stack)
    ; what do I return(in eax)
    getChar:
        ; again, seems silly
        pop edx
    
        ; obvious
        push ebp
        mov        ebp,      esp
    
        ; make space for 4 bytes on stack
        sub        esp,      4
    
        ; overwrite return address with edx
        mov        [ebp-4],  edx
    
        ; I am guessing you are trying to get the two arguments into eax, ebx
    
        ; eax = 0
        mov        eax,      [ebp+8]
        ; ebx = strconst_0
        mov        ebx,      [ebp+4]
        ; magic is here
        movzx      eax,      word [ebx + 2 * eax + 4]
        ; push magic number
        push       eax
        ; pop ... something into eax
        pop        eax
        ; restore edx from whatever you put there...
        mov        edx,      [ebp-4]
        ; restore stack?
        add        esp,      4
    
        ; obvious
        pop        ebp
        push       edx
        ret
    

    老实说,我不知道你在做什么,如果你说的话会有所帮助 “我正在尝试创建一个函数,它接受一个?和字符串缓冲区的地址,哪个?”

    特别是, 1.我不知道getChar输入是什么,它是角色的位置吗?是别的吗? 2.我不知道getChar输出是什么,它是否存储在eax中?它发射导弹吗? 3.我不知道为什么你使用函数的返回地址进行临时存储,这很愚蠢。

    main:
        push           ebp
        mov            ebp,                esp
    
        ; getChar(0, str)
        push           str
        mov dword      eax,                0
        push           eax
        call           getChar
        add            esp,                8
    
        ; printChar(str)
        push           str
        call           printChar
        add            esp,                4
    
        mov            esp,                ebp
        pop            ebp
        ret
    
    ; char getChar(long ix, char *str)
    ; returns: char at index indicated by ix in eax register
    getChar:
        push           ebp
        mov            ebp,                esp
        push           ebx   ; save ebx to avoid unwanted side-effects
    
        mov            eax,                [ebp + 8]    ; ix
        mov            ebx,                [ebp + 12]   ; str
        add            eax,                ebx    ; eax = &(str[ix])
        mov            eax,                (eax)  ; eax = *eax = str[ix]
    
        pop            ebx  ; restore ebx
        mov            esp,                ebp
        pop            ebp
        rts
    
    str db 'this is a string.', 0
    

    这绝对不会起作用,并且纯粹出于演示目的,因为我有一段时间没有写过x86,但这个想法应该是明确的。希望它有所帮助。