Re: confused over shl
- From: Frank Kotler <spamtrap@xxxxxxxxxx>
- Date: Thu, 22 Jan 2009 23:09:07 GMT
Tim Buchanan wrote:
Hi all,
Just started to learn x86 assembly. I've been using a book I found at
the library. I'm trying to do the exercises at the end of each
chapter, but I'm stumped on one of them. I have to convert a hex
string to decimal. I've got the algorithm figured out but no luck with
writing it. Heres part of what I've got so far:
mov CX,4
Might want ecx...
...
test:
"test", although intuitive, is a terrible name for a label, since it's already the name (mnemonic) of an instruction and of a standard Unix utility. Doesn't do any harm, but potentially confusing (to a human, not to the CPU)...
shl [sum],4 ;multiply sum by 4
add [sum],AL ;add AL to running total
inc EBX ;point EBX to next digit
loop test
(AL contains a digit of EBX,
A digit, or a character? For a digit, we want only 4 bits, so we probably wanna "and al, 0Fh" before we "add" (or "or") it to "[sum]". If it's a character, there's more to do. Not entirely clear what's in al at this point...
and EBX contains the inputted hex number
to convert)
Mmmm... "contains" or "points to"? The "inc ebx" suggests it points to... an ascii string?
So my loop runs 4 times.
Okay... what does the 4 represent? Number of characters in the input string? The "number" converted from that string? Pre-calculated hex digits (one per byte?)? Or...?
My problem is that after the 3rd run, the
value of sum goes from 18 to 32 ( i think it should go to 288) and the
overflow bit is set.
The numbers, out of context, don't suggest anything offhand... I would expect the carry bit to be more useful than the overflow bit... unless you're doing signed numbers (a bit more complicated - I'd get unsigned working first).
Does anyone know what I'm doing wrong here?
Not showing enough code. :)
Using
nasm on slackware 12.2
Out of curiousity, Tim, what version of ld came with that? We've seen an issue with "Slackware 12" (12.0, I guess?) with a buggy ld. Version number ended with a date -20060616 if memory serves. In case of a file with a .bss section but no .data section, ld failed to align the sections properly - unless the .text section happens to be an "even" size - and the loader, not your masterpiece, segfaulted. A *very* perplexing bug! No indication that it's a problem here, but if it should be an issue for you, download and install a newer (or older) version of the "binutils" package. Most likely you're okay, but I thought I'd mention it just in case - it's *very* perplexing!
Now... What I assume you want to do here is to input a "text" string representing a hex number, and print out a string representing that number as decimal text. If so, you need to convert the "hex string" to a number - you're apparently using [sum] for this - then convert the number to a "decimal string" and print that. The code above looks like part of the "hex string to number" part. Are we in the same ballpark so far?
This is a quickie (aka "teaching sloppy solutions to beginners"!). It doesn't really print a "usage" message, just quits. Doesn't really do anything about "invalid",
or check for overflow - just uses any valid part it finds, and stops on any invalid digit or end-of-string. Doesn't check for errors of any kind. Uses unsophisticated inline conversion routines instead of reuseable subroutines. Just shows the "basics" in a "simple" way - there are better ways! Maybe it'll give you a hint why yours isn't working...
Best,
Frank
; nasm -f elf32 hex2dec.asm [-F dwarf (for gdb)]
; ld -o hex2dec hex2dec.o [-s (but *not* for gdb)]
global _start
section .text
_start:
nop ; makes gdb happier, if we're using it
cmp dword [esp], 2 ; have we got a parameter?
jnz usage
mov ebx, [esp + 8] ; the command line parameter
xor eax, eax ; "sum"
xor edx, edx ; make sure upper bits are clear
conv_hex:
mov dl, [ebx]
inc ebx
sub dl, '0'
jc invalid
cmp dl, 9
jbe good_digit
and dl, 0DFh ; force 'a' to 'A', etc.
sub dl, 7
cmp dl, 10
jb invalid
cmp dl, 0Fh
ja invalid
good_digit:
shl eax, 4
or eax, edx
jmp conv_hex
done:
invalid: ; todo
; "sum" is in eax - convert to decimal string
mov ebx, 10 ; divide by ten
xor ecx, ecx ; "counter"
mov edi, decimal_ascii_buffer
conv_dec:
xor edx, edx ; "div" uses edx:eax!!!
div ebx
push edx ; "remainder" in edx - save it
inc ecx ; count it
test eax, eax ; is it zero? we done! else...
jnz conv_dec
mov edx, ecx ; save count for the "write"
pop_loop:
pop eax ; fetch a digit
add al, '0' ; convert it to character
stosb ; like "mov [edi], al", "inc edi"
loop pop_loop
mov byte [edi], 10 ; throw in a linefeed
inc edx ; adjust count for it
mov ecx, decimal_ascii_buffer
mov ebx, 1 ; stdout
mov eax, 4 ; __NR_write
int 80h
usage: ; todo
exit:
mov eax, 1 ; __NR_exit
int 80h
section .bss
decimal_ascii_buffer resb 16
.
- Follow-Ups:
- Re: confused over shl
- From: Tim Buchanan
- Re: confused over shl
- References:
- confused over shl
- From: Tim Buchanan
- confused over shl
- Prev by Date: Re: confused over shl
- Next by Date: Re: confused over shl
- Previous by thread: Re: confused over shl
- Next by thread: Re: confused over shl
- Index(es):
Relevant Pages
|