Reputation: 1621
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
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
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
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