NASM - The Netwide Assembler
NASM Forum => Using NASM => Topic started by: akus85 on May 03, 2010, 04:19:59 PM
-
Hi,i'm a noob in nasm and have a problem to scan a string.
For a string "hello" i should obtain:
68
65
6C
6C
6F
Where i wrong ? ???
%include "asm_io.inc"
segment .data
;; ostring dd '1','2','3','4','5'
ostring db "hello",0
segment .bss
segment .text
global _asm_main
_asm_main:
enter 0,0
pusha
xor ebx,ebx
cycle:
cmp ebx,5
jae ex
mov eax,[ostring+ebx*1]
call print_int
call print_nl
inc ebx
jmp cycle
ex:
mov eax,0
leave
popa
ret
-
I don't have a copy of asm_io.inc, but if it works the way I think it does, then this should get you going.
%include "asm_io.inc"
segment .data
ostring db "hello"
ostring_size equ ($-ostring)
segment .bss
segment .text
global _asm_main
_asm_main:
enter 0,0
pusha
xor ebx,ebx
xor eax,eax
cycle:
push ebx
mov al,[ostring+ebx*1]
call print_int
call print_nl
pop ebx
inc ebx
cmp ebx, ostring_size
jl cycle
ex:
mov eax,0
leave
popa
ret
I'm assuming that ebx is being corrupted by either print_int or print_nl. When I rewote this to make use of libc it worked fine. So I'm pretty certain that's your problem.
-
my error was here :
mov eax,[ostring+ebx*1] ---> mov al,[ostring+ebx*1]
Thaks ;)
For information asm_io.inc is :
extern read_int, print_int, print_string
extern read_char, print_char, print_nl
extern sub_dump_regs, sub_dump_mem, sub_dump_math, sub_dump_stack
%macro dump_regs 1
push dword %1
call sub_dump_regs
%endmacro
;
; usage: dump_mem label, start-address, # paragraphs
%macro dump_mem 3
push dword %1
push dword %2
push dword %3
call sub_dump_mem
%endmacro
%macro dump_math 1
push dword %1
call sub_dump_math
%endmacro
%macro dump_stack 3
push dword %3
push dword %2
push dword %1
call sub_dump_stack
%endmacro
-
The relevant code is actually in asm_io.asm (which is assembled to asm_io.o and linked with your code)...
print_int:
enter 0,0
pusha
pushf
push eax
push dword int_format
call _printf
pop ecx
pop ecx
popf
popa
leave
ret
As you can see, it even preserves flags (print_nl likewise). You should be able to remove the "push ebx", "pop ebx" (both or neither, please!) and still have it work. What Bryant did that actually fixed it was:
xor eax,eax
cycle:
push ebx
mov al,[ostring+ebx*1]
instead of:
mov eax,[ostring+ebx*1]
With eax there, you get 4 bytes of your string in eax, and print_int prints all 4 of 'em as a single number. By zeroing eax first, and then loading just al from your string, print_int prints all of eax as a single number - but it's the number we want. :)
Or is it? Your example appears to show the bytes of the string represented in hex. That's not what print_int does (it prints a decimal representation). It would be trivial (for an experienced programmer) to add a "print_hex" function - a duplicate of "print_int", but with "push dword hex_format"... added above as hex_format db "%X", 0... add print_hex to the list of globals here, and to the list of externs in asm_io.inc... reassemble asm_io.asm... and you should be able to use print_hex just like print_int. I don't imagine you're supposed to do that as homework, though. :)
If it's really supposed to be hex, you may be expected to convert to a hex representation and use print_char to display it. If that's the case, you have more work to do. :(
Best,
Frank
-
What Bryant did that actually fixed it was:
xor eax,eax
cycle:
push ebx
mov al,[ostring+ebx*1]
instead of:
mov eax,[ostring+ebx*1]
Yea, I have a habit of subliminally correcting things like that when I'm "fixing" code to work on my setup. I had to change this code from print_int/print_nl to use printf() so I instinctively modified the mov al, [ostring+ebx*1]. :D