Progrmr
Progrmr

Reputation: 1621

nasm x86-64 assembly - two variables read as one variable

I am making a simple program to print "Hello, world!" in hex ASCII characters. Here is my code:

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

MY QUESTION:

How can I do something like this:

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

What I mean is how can I have a variable and an incrementing counter be read as one variable?

Thanks in advance.

Upvotes: 0

Views: 1151

Answers (3)

Frank Kotler
Frank Kotler

Reputation: 1452

Wait a minute. Did you want to print hex values (in text) of the characters instead of the characters? Something like this? (highly unoptimized)

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

Upvotes: 0

Frank Kotler
Frank Kotler

Reputation: 1452

Putting the character into ecx isn't going to work! (segfault) ecx wants to be the address (offset).

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

... something like that... If you really want 64-bit code, the system call numbers are different - 1 for write and... 3Ch(?) for exit. Use syscall instead of 'int 80h` (and 64-bit regs, of course). If you want to do 32-bit code with a 64-bit ld, tell ld "-m elf_i386".

Upvotes: 0

Necrolis
Necrolis

Reputation: 26171

You'd need to make an array out for your string, the same way msg is declared, the load the pointer to that string, dereference to get that character, check if its 0, break if so, else print and increment the pointer.

eg: (MASM syntax, sorry)

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

Just noticed that your title states x86-64, but your code (and my code), is plain x86, if you are actually wanting x64 code, the ABI for the syscall's changes a bit, but the rest is pretty much the same.

Upvotes: 1

Related Questions