0

「Hello, world!」を印刷する簡単なプログラムを作成しています。16 進 ASCII 文字で。これが私のコードです:

SECTION .DATA
msg db 'Printing Hello world in ASCII values: ', 0
msglen EQU $-msg
char1 db 064h  ; 'd' character
char2 db 06Ch  ; 'l' character
char3 db 072h  ; 'r' 
char4 db 06Fh  ; 'o'
char5 db 077h  ; 'w'
char6 db 020h  ; (space)
char7 db 06Fh  ; 'o'
char8 db 06Ch  ; 'l'      
char9 db 06Ch  ; 'l'
char10 db 065h ; 'e'
char11 db 048h ; 'H'

SECTION .bss

SECTION .text

GLOBAL _start:
_start:
nop
mov esi, 0

mov eax, 4
mov ebx, 1
mov ecx, msg
mov edx, msglen
int 80h
; printing 'H'
mov eax, 4
mov ebx, 1  
mov ecx, char11 
mov edx, 1
int 80h

; printing 'e'
mov eax, 4
mov ebx, 1  
mov ecx, char10
mov edx, 1
int 80h

; printing 'l'
mov eax, 4
mov ebx, 1  
mov ecx, char9
mov edx, 1
int 80h     

; printing 'l'
mov eax, 4
mov ebx, 1  
mov ecx, char8 
mov edx, 1
int 80h 

; printing 'o'
mov eax, 4
mov ebx, 1  
mov ecx, char7 
mov edx, 1
int 80h 

; printing space
mov eax, 4
mov ebx, 1  
mov ecx, char6 
mov edx, 1
int 80h 

; printing 'w'
mov eax, 4
mov ebx, 1  
mov ecx, char5 
mov edx, 1
int 80h

; printing 'o'
mov eax, 4
mov ebx, 1  
mov ecx, char4 
mov edx, 1
int 80h

; printing 'r'
mov eax, 4
mov ebx, 1  
mov ecx, char3 
mov edx, 1
int 80h

; printing 'l'
mov eax, 4
mov ebx, 1  
mov ecx, char2 
mov edx, 1
int 80h

; printing 'd'
mov eax, 4
mov ebx, 1  
mov ecx, char1 
mov edx, 1
int 80h

    ; end
mov eax, 1
mov ebx, 0
int 80h

私の質問:

どうすればこのようなことができますか:

loop:
    mov eax, 4
    mov ebx, 1
    mov ecx, char[incremented variable]
    mov edx, 1
    int 80h
    inc (incremented variable)
    jmp loop

つまり、変数とインクリメント カウンターを 1 つの変数として読み取る方法を教えてください。

前もって感謝します。

4

3 に答える 3

1

文字列の配列を作成する必要があります。同じ方法msgで宣言し、その文字列へのポインターをロードし、その文字を取得するために逆参照し、0 かどうかを確認し、そうであればブレークし、そうでなければポインターを出力してインクリメントします。

例: (MASM 構文、申し訳ありません)

msg2 BYTE "Hello World!",0

MOV ESI, OFFSET msg2

LOOP1:

MOVZX ECX, BYTE PTR[ESI]
TEST ECX,ECX
JE NEXT
MOV EAX, 4
MOV EBX, 1
MOV EDX, 1
INT 80h
INC ESI
JMP LOOP1

NEXT:
...

タイトルには x86-64 と記載されていますが、コード (および私のコード) は単純な x86 であることに気付きました。実際に x64 コードが必要な場合は、syscall の ABI が少し変更されますが、残りはほぼ同じです。

于 2012-10-11T08:51:08.127 に答える
0

ちょっと待って。文字の代わりに文字の 16 進値を (テキストで) 印刷したかったですか? このようなもの?(高度に最適化されていません)

global _start

section .data
    msg db "Hello World", 0
    hexbuf db "0xXX, "
    hexbuflen equ $ - hexbuf

section .text
_start:
mov esi, msg
looptop:
    mov al, [esi]
    test al, al
    jz done
    inc esi
    mov ah, al
    and al, 0Fh
    cmp al, 9
    jna skip
    add al, 7
skip:
    add al, '0'
    mov [hexbuf + 3], al
    mov al, ah
    shr al, 4
    and al, 0Fh
    cmp al, 9
    jna skip2
    add al, 7
skip2:
    add al, '0'
    mov [hexbuf + 2], al
    mov edx, hexbuflen
    mov ecx, hexbuf
    mov ebx, 1
    mov eax, 4
    int 80h
    jmp looptop
done:
    push 10
    mov ecx, esp
    mov edx, 1
    mov ebx, 1
    mov eax, 4
    int 80h
    add esp, 4

    mov eax, 1
    xor ebx, ebx
    int 80h
;-----------------

于 2012-10-11T16:25:48.700 に答える
0

キャラクターを ecx に入れてもうまくいきません! (segfault) ecx はアドレス (オフセット) になりたがっています。

mov ecx, mystring ; address! (Masm uses "offset")
looptop:
cmp byte [ecx], 0 ; "[contents]"
jz done
mov edx, 1 ; length
mov ebx, 1 ; stdout
mov eax, 4 ; __NR_write
int 80h
inc ecx ; next address
jmp  looptop
done:
...

...そのようなもの...本当に64ビットコードが必要な場合、システムコール番号は異なります-書き込み用の1と...終了用の3Ch(?)。syscall'int 80h' (もちろん 64 ビット reg) の代わりに使用します。64 ビット ld で 32 ビット コードを実行する場合は、ld に「-m elf_i386」と指定します。

于 2012-10-11T12:46:01.393 に答える