2017-04-23 82 views
0

我想在NASM汇编程序中使用strstr C函数,但似乎无法使其正确打印出来。我尝试了多种变化,但我想我可能会误解NASM如何从C返回指针值,因为我在printf或'(null)'中返回空行。为什么我无法获得正确的印刷回报值?有些人可以帮我填补吗?在NASM中使用strstr()的返回值?

section .data 

    str1 db "Here is some text with a word",0x0A,0x00 
    str2 db "text",0x0A, 0x00 
    strFmt db "%s",0x0A,0x00 

    global _start 
    extern printf 
    extern strstr 

section .text 

_start: 

    push ebp 
    mov ebp, esi 

    push str2 
    push str1 
    call strstr 
    add esp, 8 

    mov dword [myString], eax 

    push dword [myString] 
    push strFmt 
    call printf 
    add esp, 8 

_exit: 
    mov ebx, 0 
    mov eax, 1 
    int 0x80 
+0

这看起来像一个错字:'mov ebp,esi'。我敢打赌,你的意思是来源于'esp'那里。另外,什么是'myString'?即使您使用它,这也未在您所展示的代码中定义。为什么不直接'直接推eax'? –

+0

我看到你使用'int 0x80',所以我认为这是Linux或macOS。请下次在您的问题中添加此信息。 Windows上的情况稍有不同。 –

回答

1

主要问题是搜索字符串中的0x0A。它是字符串的一部分,因为终止null之前的所有内容都是它的一部分。它必须单独列出,因为C-style escape sequences内部的字符串不会被汇编程序解析。 strstr将不会找到“test \ n”。删除0x0Astrstr将找到搜索字符串。

正如科迪格雷提到的,与mov ebp, esi块是奇怪的 - 你可能意味着惯用的mov ebp, esp。而且,这个例子中并不需要。直接与myString -just push eax间接也是多余的。

printf首先将输出写入缓冲区。您通过系统调用int 80h退出程序。这个调用会破坏包括printf缓冲区在内的所有进程。所以缓冲区不会被输出。有两种方法来解决这个问题:

1)使用C函数exit而不是系统调用:

section .data 
    str1 db "Here is some text with a word",0x0A,0x00 
    str2 db "text",0x00 
    strFmt db "%s",0x0A,0x00 

global _start 
extern printf, strstr, exit 

section .text 

_start: 

    push str2 
    push str1 
    call strstr 
    add esp, 8 

    push eax 
    push strFmt 
    call printf 
    add esp, 8 

_exit: 
    push 0 
    call exit 

2)调用添加到C函数fflush

section .data 
    str1 db "Here is some text with a word",0x0A,0x00 
    str2 db "text",0x00 
    strFmt db "%s",0x0A,0x00 

global _start 
extern printf, strstr, fflush 

section .text 

_start: 

    push str2 
    push str1 
    call strstr 
    add esp, 8 

    push eax 
    push strFmt 
    call printf 
    add esp, 8 

    push 0 
    call fflush 

_exit: 
    mov ebx, 0 
    mov eax, 1 
    int 0x80 
+0

感谢您的帮助。是的,我的意思是有esp,而不是esi。另外,我错过了复制我定义myString的section .data。有没有办法从读入的输入命令行参数中移除像0x0A这样的空终止符?因此,不是使用str2,而是使用strstr在str1中搜索命令行参数字符串。我试过这样做,但是当你在命令行中读取arg时,你会在字符串的末尾得到终止字符。 –

+0

@SamIvanecky:0x0A不是空终止符,而是换行符(=换行符)。空终止符是0x00,不是字符串的一部分,它表示C函数结束字符串,不应该被删除。可能有很多原因导致您无法访问命令行。您应该使用相应的[MCVE](http://stackoverflow.com/help/mcve)提出一个新问题。 – rkhb