Reputation: 89
I'm writing a program to search for vowels inside a string, but I'm having trouble testing the individual characters inside the string, I have the basic concept down and I've done this before using C++ and Python, but I don't know how to code it in Assembly.
I'm going to use a switch to add up and test the individual characters, and I know that I need to use a loop to cycle through all the characters, but I'm stuck on actually testing individual characters. (this isn't what I have coded per say but an illustrative example)
max_length dd 40
user_input resd max_length
str_len dw $ - user_input
GetStr user_input ; "I am a boy"
mov ecx, str_len
And this is where I get stuck. How would you test the individual characters of user_input
?
In C++ you would have something like if(user_input[0] = 'Y')
, but how do I translate that type of instruction to assembly (user_input[0])
I understand that it does not work this way in assembly but hopefully this will clear some things up.
str_len DW $ - user_input
max_length EQU 40
jump_table:
DD case_0
DD case_1
DD case_2
DD case_3
DD case_4
DD case_5
.UDATA
user_input resd max_length
_main:
push ebp
mov ebp, esp
switch:
xor eax,eax
xor ebx,ebx
PutStr prompt
GetStr user_input
mov ecx, [str_len]
mov esi, user_input
read:
mov al, byte [esi+ebx]
or al, 20h
cmp al, 'a'
je [jump_table]
cmp al, 'e'
je [jump_table+4]
cmp al, 'i'
je [jump_table+8]
cmp al, 'o'
je [jump_table+12]
cmp al, 'u'
je [jump_table+16]
cmp ecx, 0
je [jump_table+20]
inc ebx
jmp read
this is where I am now, as I commented further down I'm getting an error linked to str_len
This is all working, I just need to clear the buffer, Thanks! str_len DD 40 max_length EQU 40
jump_table:
DD case_0
DD case_1
DD case_2
DD case_3
DD case_4
DD case_5
.UDATA
user_input resb max_length
.CODE
.STARTUP
switch:
xor eax,eax
xor ebx,ebx
xor esi, esi
PutStr prompt
GetStr user_input
mov ecx, [str_len]
mov esi, user_input
read:
mov al, byte [esi+ebx]
or al, 20h
;PutCh al
cmp al, 'a'
je vowel_A
cmp al, 'e'
je vowel_E
cmp al, 'i'
je vowel_I
cmp al, 'o'
je vowel_O
cmp al, 'u'
je vowel_U
cmp ecx, 0
je str_end
inc ebx
dec ecx
jmp read
Upvotes: 0
Views: 11461
Reputation: 5884
mov EAX, [user_input]
would NOT load the string into eax
but the first 4 bytes of the string.
user_input
is a pointer.
mov esi, user_input
xor ebx, ebx
SearchForVowel:
mov al, byte [esi + ebx]
test al, al ; does al contain a 0
jz .Done ; yes we are done.
; check to see if al contains a vowel
if al does not contain a vowel, jump to NoVowel
otherwise, increment vowel_counter
.NoVowel:
inc ebx
jmp SearchForVowel
.Done:
No need to store the string length since strings should be NULL terminated.
Upvotes: 0
Reputation: 95326
What you appear to be missing is the notion of indexed addressing.
If you don't know this, you really need to back to assembler 101 class or you aren't going to make much progress. I'm sure you can find a tutorial on the web.
The key ideas are a) registers contain arbitrary values, interpreted either as "just a number" or interpreted as a memory address, b) you can combine such values to fetch/store things to memory. Given that a register (esi) contains a pointer to the base of the string, and the register ecx contains an index into the string, the instruction
mov al,[edx+ecx]
will fetch an 8 bit value to the AL register. The instruction tells the computer to add the values in edx and ecx to form a memory address, and fetch whatever is in that location. A related instruction:
mov [edx+ecx],al
computes the same address, but moves what is in AL into memory.
Unfortunately for you, the x86 CPU has complicated rules about what is allowed in forming a memory address using indexed addressing, and additional rules about how the size of the operand (8,16,32,64) in bits is specified. This isn't the place for a full tutorial, which is why I suggest you do a bit more homework before proceeding.
Upvotes: 1