2012-10-11 5 views
0

"Hello, world!"라는 간단한 프로그램을 만들고 있습니다. 16 진수 ASCII 문자. 다음은 내 코드입니다 :nasm x86-64 어셈블리 - 두 변수가 하나의 변수로 읽습니다.

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

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에 나타났습니다,하지만 코드 (그리고 내 코드), 일반 86이며, 실제로 64 코드를하고자하는 경우, 시스템 콜의 ABI는 약간 변경되었지만 나머지는 거의 동일합니다.

+0

어떻게 수행 할 지에 대한 예제 코드를 제공해 주시겠습니까? – Progrmr

+0

@AussieGamer : 방금 하나 추가했습니다. 불행히도 nasm을 사용하지 않으므로 masm 구문을 사용해야했습니다. 그러나 이들은 대략 동일합니다. – Necrolis

+0

예, 저는 64 비트 Linux 시스템을 사용하고 있습니다. 나는 MASM 어셈블리를 사용했지만 리눅스로 바꿨다. 나는 또한 배열을 사용하여 주위에 적이 없으므로이 게시물을. – Progrmr

0

문자를 ecx에 넣는 것은 효과가 없습니다! (segfault) ecx는 주소 (offset)가되고 싶어합니다. 당신이 정말로 64 비트 코드를 원하는 경우

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: 
... 

는 ... 그런 일이 ..., 시스템 호출 번호는 다른 - 1 쓰기 및 ... 3CH 종료를위한 (?). 'int 80h'(물론 64 비트 regs) 대신 syscall을 사용하십시오. 64 비트 ld로 32 비트 코드를 작성하려면 ld "-m elf_i386"을 지정하십시오.

+0

리눅스에서 마스문과 유사한 문법을 ​​사용하려면 Jwasm ("japheth.de"think) 또는 (G)를 ".intel-syntax noprefix"와 같이 사용하십시오. –

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 
;----------------- 

관련 문제