0

我正在制作一个简单的程序来打印“你好,世界!” 以十六进制 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

我的意思是如何将一个变量和一个递增计数器作为一个变量读取?

提前致谢。

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 代码,系统调用的 ABI 会发生一些变化,但其余部分几乎相同。

于 2012-10-11T08:51:08.127 回答
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 位 regs)。如果你想用 64 位 ld 做 32 位代码,告诉 ld “-m elf_i386”。

于 2012-10-11T12:46:01.393 回答
0

等一下。您是否要打印字符的十六进制值(以文本形式)而不是字符?像这样的东西?(高度未优化)

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 回答