Author Topic: what's wrong with the code?  (Read 17576 times)

Offline maplesirop

  • Jr. Member
  • *
  • Posts: 60
what's wrong with the code?
« on: February 25, 2013, 01:46:31 AM »
Code: [Select]
mov eax, 4
mov ebx, 1
mov ecx, promptUser
mov edx, len
int 0x80

mov eax, 3
mov ebx, 0
mov ecx, userInput
mov edx, 10
int 0x80

mov eax, 4
mov ebx, 1
int 0x80              : everything works until here

cmp ecx, 1
jle elseif
cmp ecx, 20
jge elseif
mov eax, 4
mov ebx, 1
mov ecx, if
mov edx, ifLen
int 0x80               : doesn't work




label1: cmp ecx, 21
jle aelseif
cmp ecx, 41
jge aelseif
mov eax, 4
mov ebx, 1
mov ecx, aIf
mov edx, aIfLen
int 0x80               : doesn't work

Do I have to add this: str2int data so that we can compare ecx with decimal numbers?

Also do I have to remove int0x80, because it erase the value of ecx?

Code: [Select]
mov eax, 4
mov ebx, 1
mov ecx, promptUser
mov edx, len
int 0x80

mov eax, 3
mov ebx, 0
mov ecx, userInput
str2int data           : converts userInput intro decimal int
mov edx, 10
int 0x80

mov eax, 4
mov ebx, 1
int 0x80 : everything works until here

cmp ecx, 1
jle elseif
cmp ecx, 20
jge elseif
mov eax, 4
mov ebx, 1
mov ecx, if
mov edx, ifLen
int 0x80            : doesn't work




label1: cmp ecx, 21
jle aelseif
cmp ecx, 41
jge aelseif
mov eax, 4
mov ebx, 1
mov ecx, aIf
mov edx, aIfLen
int 0x80           : doesn't work

Offline Gunner

  • Jr. Member
  • *
  • Posts: 74
  • Country: us
    • Gunners Software
Re: what's wrong with the code?
« Reply #1 on: February 25, 2013, 02:53:51 AM »
You will get more help if you post your complete code, that includes all your variables, not just code snippets.

Code: [Select]
mov eax, 3
mov ebx, 0
mov ecx, userInput
str2int data           : converts userInput intro decimal int
mov edx, 10
int 0x80

eax, is the type of system call, but str2int, I am guessing, returns the dword in eax so the value 3 for the system call is now overwritten.

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: what's wrong with the code?
« Reply #2 on: February 25, 2013, 04:09:01 AM »
Code: [Select]
; prompt user

mov eax, 3
mov ebx, 0
mov ecx, userInput
str2int data           : converts userInput intro decimal int
mov edx, 10
int 0x80
;...

It looks like you've inserted this macro (from nagoa.inc?) into the middle of a sys_read. It's going to work better if you finish reading the string before you convert it to integer. :)

This macro expects a zero-terminated string (as its parameter - where you've got "data), which sys_read is not going to give you (we can zero-terminate it easily). It puts the number in eax - ecx is going to be zero on exit from the macro. I can't imagine that your next sys_write is going to work, although the comment says it does...

Then you seem to be checking if ecx is between 2 and 19 (inclusive). It isn't clear where you jump to if ecx is less than or equal to 1, or if it's greater than or equal to 20. Then you print something(?) and fall through to checking if ecx is between 22 and 40 - it isn't, because you've changed it in printing "if".

You shouldn't have to remove any int 0x80 - it won't, in itself, change ecx... although you may need to change ecx to use it.

If you're finding that Linux isn't going to work for you, you may need to use WriteFile instead of sys_write and ReadFile instead of sys_read. In between interactions with the OS, the code should be pretty much the same... if that's any help. :)

Best,
Frank

P.S. Gunner has picked up another problem that I missed. Yeah, show us more of the code!

Offline maplesirop

  • Jr. Member
  • *
  • Posts: 60
Re: what's wrong with the code?
« Reply #3 on: February 25, 2013, 04:36:39 AM »
Code: [Select]
segment .data

promptUser db "enter something", 10, 0
len equ $ -promptUser

if db "ok", 10, 0
ifLen equ $ -if

aif db "ok", 10, 0
aifLen equ $ -aif

segment .bss

userInput 1: it's 1 char

global _start

_start

mov eax, 4
mov ebx, 1
mov ecx, promptUser
mov edx, len
int 0x80

mov eax, 3
mov ebx, 0
mov ecx, userInput
str2int data           : converts userInput intro decimal int
mov edx, 10
int 0x80

mov eax, 4
mov ebx, 1
int 0x80 : everything works until here

cmp ecx, 1
jle elseif
cmp ecx, 20
jge elseif
mov eax, 4
mov ebx, 1
mov ecx, if
mov edx, ifLen
int 0x80            : doesn't work




label1: cmp ecx, 21
jle aelseif
cmp ecx, 41
jge aelseif
mov eax, 4
mov ebx, 1
mov ecx, aIf
mov edx, aIfLen
int 0x80           : doesn't work

Offline maplesirop

  • Jr. Member
  • *
  • Posts: 60
Re: what's wrong with the code?
« Reply #4 on: February 25, 2013, 04:40:17 AM »
Code: [Select]
; prompt user

mov eax, 3
mov ebx, 0
mov ecx, userInput
str2int data           : converts userInput intro decimal int
mov edx, 10
int 0x80
;...

It looks like you've inserted this macro (from nagoa.inc?) into the middle of a sys_read. It's going to work better if you finish reading the string before you convert it to integer. :)

This macro expects a zero-terminated string (as its parameter - where you've got "data), which sys_read is not going to give you (we can zero-terminate it easily). It puts the number in eax - ecx is going to be zero on exit from the macro. I can't imagine that your next sys_write is going to work, although the comment says it does...

Then you seem to be checking if ecx is between 2 and 19 (inclusive). It isn't clear where you jump to if ecx is less than or equal to 1, or if it's greater than or equal to 20. Then you print something(?) and fall through to checking if ecx is between 22 and 40 - it isn't, because you've changed it in printing "if".

You shouldn't have to remove any int 0x80 - it won't, in itself, change ecx... although you may need to change ecx to use it.

If you're finding that Linux isn't going to work for you, you may need to use WriteFile instead of sys_write and ReadFile instead of sys_read. In between interactions with the OS, the code should be pretty much the same... if that's any help. :)

Best,
Frank

P.S. Gunner has picked up another problem that I missed. Yeah, show us more of the code!

thanks

umm... do i have to convert ecx into a decimal integer? if so, what do i need to do?

Basically I have to check what the character entered is

if its ASCII code is between @ and c, i print something. If it's between d and A, I print something and then so on...

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: what's wrong with the code?
« Reply #5 on: February 25, 2013, 06:12:57 AM »
Oh!

Here's what I thought you were trying to do:
Code: [Select]
; nasm -f elf32 myfile.asm
; ld -o myfile myfile.o (-melf_i386 for 64-bit systems)

global _start


;;================================
;; MACRO  str2int     int2str by Written by mastercpp.
;;================================
%macro str2int 1
        push    ebx ;
        push    esi ;
        push    edi ;
        mov ebx, 0
        mov ecx, 0
        xor eax,eax
        mov ebx,0000000Ah
;        mov esi,offset %1
; offset??? who said that swearword? :)
        mov esi, %1
        %%ConvertLoop:
        movzx ecx,byte [esi] ;Zeichen laden.
        test ecx,ecx
        jz  short %%ExitConvertLoop ;0 => Exit
        inc esi
        sub cl,30h ;0-9...
        mul ebx ;Ergebnis * 10
        add eax,ecx ;+ nächste Ziffer
        jmp short %%ConvertLoop
        %%ExitConvertLoop:
        pop     edi
        pop     esi
        pop     ebx
%endmacro

%macro int2str 2
        push    ebx ;
        push    esi ;
        push    edi ;
        %%start:
        mov  eax, %1
        xor  ecx, ecx
        mov  ebx, 000ah
        %%DecConvert:
        xor  edx,  edx
        div  ebx
        add  edx,  0030h
        push edx
        inc  ecx
        or   eax,  eax
        jnz  short %%DecConvert
        mov  edi,  %2
        mov edx,ecx
        %%SortDec:
        pop   eax
        stosb
        loop  %%SortDec
        mov eax, 0h
        stosb
        pop     edi
        pop     esi
        pop     ebx
%endmacro
;;================================
;; mastercpp  end macros
;;================================


section .data
    promptUser db "you know what to do", 10
    len equ $ - promptUser
    if db 10, "between 2 and 19", 10
    ifLen equ $ - if
    aIf db 10, "between 22 and 40", 10
    aIfLen equ $ - aIf

section .bss
theNumber resd 1
userInput resb 11


section .text
_start:

mov eax, 4
mov ebx, 1
mov ecx, promptUser
mov edx, len
int 0x80

mov eax, 3
mov ebx, 0
mov ecx, userInput
mov edx, 10
int 0x80

push eax  ; save the length

mov byte [ecx + eax - 1], 0  ; zero-terminate the sucker!

str2int userInput           ; converts userInput intro decimal int
mov [theNumber], eax


mov eax, 4
mov ebx, 1
mov ecx, userInput
pop edx  ; get the length back
int 0x80 ; everything works until here


mov ecx, [theNumber]

cmp ecx, 1
jle elseif
cmp ecx, 20
jge elseif

mov eax, 4
mov ebx, 1
mov ecx, if
mov edx, ifLen
int 0x80            ; doesn't work

jmp endif


elseif: ; ?
label1: cmp ecx, 21
jle aelseif
cmp ecx, 41
jge aelseif

mov eax, 4
mov ebx, 1
mov ecx, aIf
mov edx, aIfLen
int 0x80           ; doesn't work

jmp endif

aelseif:
; print "none of the above"


endif:
mov eax, 1
xor ebx, ebx
int 0x80

No, if you want to check ascii codes, you don't have to convert to a number. However, ecx is the address of where the victim ("user", I mean!) put his masterwork. You could do something like...
Code: [Select]
cmp byte [ecx], '@'
jb someplace
or perhaps better...
Code: [Select]
mov al, [ecx] ; or the name of the buffer
cmp al, '@'
jb someplace
cmp al, '9'
ja someplace
; do your @ - 9 thing
jmp outtahere
someplace:
cmp al, ... whatever

Notice I changed jg and jl to ja and jb. jg and jl are for signed comparisons, ja and jb are for unsigned comparisons. Since we won't be seeing any negative ascii codes, unsigned is correct. It won't cause you any trouble in this case, either way. I left it as signed (and exclusive) in "my version", even though "mastercpp"s macro won't return negative numbers, 'cause I was gonna show you a better way... but that's not what you're trying to do...

See, like Gunner told you, we can help you better if you give us more information! :)

After looking at your latest code...
Code: [Select]
...
userInput 1: it's 1 char
I suppose you mean "resb". With the colon in there instead of a semicolon, it won't even assemble!
Code: [Select]
mov edx, 10
int 0x80
Overflowing your buffer a bit there!

Best,
Frank


Offline maplesirop

  • Jr. Member
  • *
  • Posts: 60
Re: what's wrong with the code?
« Reply #6 on: February 25, 2013, 03:35:55 PM »
thanks, but uhm I want to keep things simple and the code you've given me is a little bit too complex for me right now. also, do i have to convert a char to a number if I want to use decimal number in cmp statements? and is there a way to convert a char into a int decimal without using a macro? I only want to use "native" codes.

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: what's wrong with the code?
« Reply #7 on: February 25, 2013, 05:23:43 PM »
Quote
thanks, but uhm I want to keep things simple and the code you've given me is a little bit too complex for me right now.
Okay. I try to keep the code as simple as possible to do the job. My problem, at this point, is that I don't know what the "job" is. I thought I knew, but I'm getting more and more confused as I go along. Can we start over? What are you trying to do?
Quote
also, do i have to convert a char to a number if I want to use decimal number in cmp statements?
A number is a number. You can represent a number as decimal, or hex, or octal, or binary... or as an ascii character, if it's a printable ascii character. Still the same number.
Code: [Select]
cmp byte [ecx], '@'
cmp byte [ecx], 64 ; decimal
cmp byte [ecx], 0x40 ; hexadecimal
cmp byte [ecx], 100q ; octal
cmp byte [ecx], 0100_0000b
All of those lines produce exactly the same code.
Quote
and is there a way to convert a char into a int
A "char" is 8 bits. What's an "int"? 32 bits? You can sign extend 8 bits to 32 bits. You can zero extend it, too... but then it'd be an "unsigned int". If the "char" is "true ascii" (high bit clear), it wouldn't make any difference.
Quote
decimal
Sure, you can represent it as decimal.
Quote
without using a macro?
Sure. In fact, I think a macro is a poor way to do it. A subroutine would be better, IMO. But I'm not certain whether you need to do anything at all.
Quote
I only want to use "native" codes.
I don't know which ones are "native". A macro is just cut-and-paste. You never "have" to use a macro, they're just a convenience...

Best,
Frank


Offline maplesirop

  • Jr. Member
  • *
  • Posts: 60
Re: what's wrong with the code?
« Reply #8 on: February 25, 2013, 06:12:42 PM »
I have to enter an input from the keyboard and look if the char is between @ and a or between b and h or between h and z.

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: what's wrong with the code?
« Reply #9 on: February 25, 2013, 08:00:22 PM »
Okay... you know how to get input from the keyboard (I guess). Forget about "converting" anything to anything - that was a false alarm. Where you seem to be going wrong is thinking that the character is going to be in ecx. It is not, it's going to be in memory pointed to by ecx - in [ecx] if you look at it that way. Nasm is going to need to be told "byte", since [ecx] could point to any size value. If we use an 8-bit register, Nasm knows we want "byte" without us having to say so. That's the way I'd do it...
Code: [Select]
mov al, [ecx]
Or... it might be clearer if we do...
Code: [Select]
mov al, [userInput]
ASSuming that ecx still points to userInput, as it was for the sys_read, they're the same thing. Then you can go on to compare the character to various things. You can look up the number associated with '@' (etc.) and use the numbers, but I think your code will be a lot more readable if you just call it '@'. Programmer's choice.

Randy Hyde tells me that this "if" concept is something beginners have a lot of trouble with. We don't have an instruction that says "if condition, do these next few instructions". What we have are instructions that say "if condition, goto". I know "goto" has a bad reputation in some circles, but that's the instruction we have. So what we need to do is "if not condition, goto someplace after these next few instructions". Read over some of the examples above with that in mind and see if it becomes any clearer.

After doing the "if clause", we may want to "fall through" into the following code, or we may want to "jmp someplace else". Think through what you want to do in each case - essentially the difference between having an "else" or "elif" clause or not... Keep in mind that we WILL fall through unless we do something else...

We've been discussing Linux code. Last we heard from you on the subject, you were having trouble running Linux. If you can run some simple programs, you can learn a lot by "trying things". If you can't, it's going to be a lot harder! Since you've been posting code that won't even assemble, I suspect that you may still be having trouble with that. If it were me, I'd format the accursed Windows drive and install Linux, but that may not be a good solution for you. Can you run Linux from a "live CD"? Can you install Dosbox? (I can't get DosBox to build, so I haven't been able to try it) Dos is pretty useless, but some simple user I/O is pretty easy to learn. Windows isn't "that" hard to learn. This'll go a lot easier for you if you can "try things"!

Best,
Frank


Offline maplesirop

  • Jr. Member
  • *
  • Posts: 60
Re: what's wrong with the code?
« Reply #10 on: February 26, 2013, 04:54:27 AM »
omg, thanks. you made my day. i was so depressed this morning, now i am happy as hell.