-1

char ポインターを取得する必要があり、その後、画面に出力して、正常に動作するかどうかを確認します。ファイルからテキストを読み取り、char ポインター (sizeof(char*) + filesize) + 1.. に入れます。最後に '\0' を入れます。char* を printf した場合は問題ありません。ここに私の asm コードを示します。

; void processdata(char* filecontent);
section .text
    global processdata
    extern printf
section .data
FORMAT: db '%c', 10, 0 ; to break the line 10, 0
processdata:
    push ebp
    mov ebp, esp
    mov ebx, [ebp]
    push ebx
    push FORMAT
    call printf
    add esp, 8

実行すると、変数にゴミが表示されます。

バイオレットが言ったように:

; void processdata(char* filecontent);
section .text
        [GLOBAL processdata] ;global processdata 
        extern printf
section .data
FORMAT: db '%c', 0
EQUAL: db "is equal", 10, 0
processdata:

    lea   esi,  [esp]
    mov   ebx,  FORMAT 
oook:   
    mov   eax,  [esi]
    push  eax
    push  ebx 
    call  printf
    inc   esi
    cmp  esi, 0x0
    jnz  oook

ありがとう

4

2 に答える 2

1

悪魔の夜を引用

しかし、インクリメントする必要がある場合、それを行うことはできますか?

元の関数引数char*%cフォーマットを使用すると、次のようになります。

    lea   esi,  [esp+4]
    mov   ebx,  FORMAT 
oook:   
    mov   eax,  [esi]
    push  eax
    push  ebx 
    call  printf
    inc   esi
    cmp  [esi], 0x0
    jnz  oook


[編集: わかりました、私はそれをいくつかの shenzi winOS インライン__asmブロックにすばやくハッキングしました]
Linux と nasm で行われた完全な処理は次のとおりです。

; ----------------------------------------------------------------------------
; blah.asm
; ----------------------------------------------------------------------------  

        extern  printf


        SECTION .data                   ;local variables
        fmt: db "next char:%c", 10, 0   ;printf format, "\n",'0'


        SECTION .text                   ;hack in some codes XD
        global foo

foo:                                    ;foo entry
        push  ebp                       ;set up stack frame
        mov   ebp,esp

        mov   esi, [ebp+8]              ;load the input char array to the source index

oook:                                   ;loop while we have some chars
        push  dword [esi]               ;push next char addy in string to stack
        push  dword fmt                 ;push stored format string to stack

        call  printf

        add   esp, 8                    ;restore stack pointer 
        inc   esi                       ;iterate to next char
        cmp   byte [esi], 0             ;test for null terminator byte 
        jnz   oook

        mov   esp, ebp                  ;restore stack frame
        pop   ebp

        mov   eax,0                     ;return 0
        ret                             ;done


blah.c (.asm foo を呼び出す):

/*-----------------------------------------------
blah.c
invokes some asm foo
------------------------------------------------*/
#include <stdio.h>

void foo(char*);

int main() {

    char sz[]={"oook\n"};
    foo(sz);

    return 0;
}


&ここにコマンドラインのものがあります:

$ nasm -f elf blah.asm -o blah.o
$ gcc -o blah blah.c blah.o
$ ./blah
next char:o
next char:o
next char:o
next char:k
next char:

$
$ nasm -v
NASM version 2.09.08 compiled on Apr 30 2011

$ uname -a
Linux violet-313 3.0.0-17-generic #30-Ubuntu SMP Thu Mar 8 17:34:21 UTC 2012 i686 i686 i386 GNU/Linux


それがあなたのために働くことを願っています;)

于 2012-05-02T19:34:21.993 に答える
0

Linux x86 では、最初の関数パラメーターはecx. ポインターを出力するための printf 形式は"%p".

だから何かに沿って

    ...
    FORMAT: db '%p', 10, 0 ; to break the line 10, 0
processdata:
    mov eax, [esp+4]
    push eax
    push format
    call printf
    add esp, 8
    ret

コードの残りの部分が正しく、gcc の呼び出し規則を使用していると仮定すると、動作するはずです。

これは、印刷したいポインタがスタック上にあると仮定しています。

クラッシュの原因はおそらく、スタックに 12 バイトをプッシュしたにもかかわらず、スタック ポインターを 8 だけ修正したためです。

于 2012-05-02T16:59:50.723 に答える