nasm x86-64程序集 - 两个变量读作一个变量

时间:2012-10-11 07:39:22

标签: assembly nasm

我正在编写一个简单的程序来打印“Hello,world!”十六进制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

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

提前致谢。

3 个答案:

答案 0 :(得分: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会有所改变,但其余的几乎是相同。

答案 1 :(得分:0)

将角色置于ecx中是行不通的! (段错)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:
...

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(?)代表退出。使用代替'int 80h`(当然还有64位regs)。如果要使用64位ld执行32位代码,请告诉ld“-m elf_i386”。

答案 2 :(得分: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
;-----------------

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