Hello, masm32 forum users. I am taking an x86 assembly language course this semester and am struggling to grasp it as well as I was able to grasp Java. As a result of this, I am having quite a bit of trouble completing a project that my professor assigned recently (which is embarassing, because it is supposed to be a novice level course). To make matters worse, I cannot actually test code myself since I get an "A1000 error" each time I attempt to do a console build all. I was wondering if some of the forum users here could assist me with the project and provide useful hints / tips that will allow me to more easily work through it. I have posted picture of the project requirements as well as my current progress (which is barely anything) below. Oh, and I will be using the MASM32 editor in order to write the code.
Project requirements: http://puu.sh/nmguK/40e9e448d6.png
Current Progress: http://puu.sh/nnMI1/27ae69be6e.png
I am currently attempting to complete the task described in the first bullet point. Since I cannot test my code, I would like to know if I have completed that task, or if I have made any mistakes (which is highly likely).
Error A1000 means probably that a file is missing. But you forgot to tell us which one.
This is the exact message: http://puu.sh/nnOg4/84e5bd0245.png
The thing is, I just checked that directory and the file is definitely there, as shown in this picture: http://puu.sh/nnOdS/8cf4a1c712.png
Does Project1 file have .asm extension ?
Quote from: GoneFishing on February 28, 2016, 10:49:49 AM
Does Project1 file have .asm extension ?
I added the esm extension after reading your comment. I also facepalmed very hard when it worked. That was so obvious, but I still didn't realize. Oh well, thank you for helping me fix that, that would have been a major problem throughout the entire semester. Hopefully someone can help me with the requirements now.
Just note that we have a firm "No Homework" rule in this forum, members will help you but only if you do your own work. Ask other people to do your work for you and you will be shown the door. :badgrin:
Quote from: ProtoflareX on February 28, 2016, 10:55:51 AMThat was so obvious
Don't worry, that happened to me, too. It is a bad habit of certain editors to save files without ending ;-)
Now go ahead and attack your agenda, step by step. We'll help you to correct errors in
your code. How much time is left? Is your teacher Kip Irvine, or do you have another reason to use his library? Here, almost everybody uses Masm32...
I've continued to work on the project since my last response. I haven't made much progress, but that's besides the point. I am currently experiencing an issue in which I get error A2006 "undefined symbol : prompt" when I attempt a console build all. The line of code containing the prompt is similar to an example that I saw in my textbook, so I'm not sure what's causing the error. I have linked pictures of my current code and the error below. Would anyone happen to know why this is occurring?
Code: http://puu.sh/noIv3/43f1c653b3.png
Error: http://puu.sh/noIGx/94ab7ed071.png
Probably assembler wants symbol prompt to be defined
Give to ML what he wants
add this to .data:
prompt BYTE "Hello I'm prompt",0
Quote from: GoneFishing on February 29, 2016, 06:08:10 AM
Probably assembler wants symbol prompt to be defined
Give to ML what he wants
add this to .data:
prompt BYTE "Hello I'm prompt",0
Ah, I see. It worked, thank you.
you probably want something like "Enter a string" as a prompt
you have some other problems, though...
first, you probably want more than a single byte for an input buffer
in fact, the ReadString function needs a buffer that will accomodate the null terminator so, at least 2 bytes are needed
i suggest you use 256 characters for the buffer
theStringArray BYTE 256 dup(?)
also, the ReadString function needs 2 registers to be set...
ReadString inputs:
EDX = offset of the input buffer
ECX = maximum characters to input (including terminal null)
so, you probably want something like
mov edx,offset theStringArray
mov ecx,sizeof theStringArray
call ReadString
Quote from: dedndave on February 29, 2016, 09:39:44 AM
you probably want something like "Enter a string" as a prompt
you have some other problems, though...
first, you probably want more than a single byte for an input buffer
in fact, the ReadString function needs a buffer that will accomodate the null terminator so, at least 2 bytes are needed
i suggest you use 256 characters for the buffer
theStringArray BYTE 256 dup(?)
also, the ReadString function needs 2 registers to be set...
ReadString inputs:
EDX = offset of the input buffer
ECX = maximum characters to input (including terminal null)
so, you probably want something like
mov edx,offset theStringArray
mov ecx,sizeof theStringArray
call ReadString
After making changes based on your comment, my current code looks like what is linked in the picture below. However, when I do a console build all, I do not receive an input prompt. Would you happen to know the reason for this?
Current code: http://puu.sh/np4w9/e8c34a000c.png
Result of "console build all": http://puu.sh/np4GL/8e454a282f.png
i sure do
you moved the ReadString call from the PROC, and placed it at the beginning of the program
it isn't very convenient that you post images of the code text
copy and paste the text into the reply window, then highlight it, then click on the # icon above the reply window
that way, we can copy and paste without having to do a lot of typing
originally, a partial looked like this
.code
main PROC
mov edx,offset theStringArray
call requestInput
EXIT
main ENDP
requestInput PROC
mov edx,offset prompt
call WriteString
call ReadString
ret
requestInput ENDP
END main
i suggested this modification
mov edx,offset theStringArray
mov ecx,sizeof theStringArray
call ReadString
you totally butchered my intent - lol
try this code...
.CODE
main PROC
mov edx,offset theStringArray
mov ecx,sizeof theStringArray
call requestInput
exit
main ENDP
requestInput PROC
push edx
push ecx
mov edx,offset prompt
call WriteString
pop ecx
pop edx
call ReadString
ret
requestInput ENDP
END main
The result of your code is linked below. I'm going to assume that isn't the desired result. It feels absolutely awful to be incapable of discerning the problem myself. Also, I'll listen to your suggestion about pasting my code in the future.
Result of your code: http://puu.sh/npcSu/e9fc74f1bd.png
that looks ok - did you try to run the program ?
Kip Irvine's library isn't very modular
so, everything gets pulled in, resulting in larger than needed EXE's
so, 9 KB might be ok
Quote from: dedndave on February 29, 2016, 01:09:31 PM
that looks ok - did you try to run the program ?
Kip Irvine's library isn't very modular
so, everything gets pulled in, resulting in larger than needed EXE's
so, 9 KB might be ok
Your code did work successfully, dedndave; I just made foolish mistake that caused me to think it didn't. Anyway, I am now attempting to solve the requirement in bullet point 2, which says: "Your program must have a procedure that accepts the address of a string and returns through EAX the length of the string". If I am correct, after the code below has finished executing, the address of the String typed in by the user is stored in EDX, right? If that is correct, then does that mean that I need to write a procedure that "USES" EDX in order to fulfill the requirement in the second bullet?
INCLUDE c:\irvine\irvine32.inc
INCLUDELIB c:\irvine\irvine32.lib
INCLUDELIB c:\masm32\lib\user32.lib
INCLUDELIB c:\masm32\lib\kernel32.lib
.data
theStringArray BYTE 256 dup(?)
prompt BYTE "Please input a String",0
.CODE
main PROC
mov edx,offset theStringArray
mov ecx,sizeof theStringArray
call requestInput
exit
main ENDP
requestInput PROC
push edx
push ecx
mov edx,offset prompt
call WriteString
pop ecx
pop edx
call ReadString
ret
requestInput ENDP
getStringLength PROC USES edx
;temporarily empty
getStringLength ENDP
END main
Quote from: ProtoflareX on March 01, 2016, 06:39:34 AMdoes that mean that I need to write a procedure that "USES" EDX
Logic is OK. I can't guarantee, though, that the address is in edx because I don't have the Irvine library.
One instruction you will need is
cmp byte ptr [edx], 0\Masm32\help\opcodes.chm has details on
cmp.
Kip Irvine's library has a function called Get_length
it isn't the greatest code in the world, but the library source does show you how it works
it is invoked with an argument - not quite what the assignment asks for
as for EDX, i think WriteString preserves all registers, so EDX will remain unaltered
Quote from: dedndave on March 02, 2016, 01:13:22 AM
Kip Irvine's library has a function called Get_length
it isn't the greatest code in the world, but the library source does show you how it works
it is invoked with an argument - not quite what the assignment asks for
as for EDX, i think WriteString preserves all registers, so EDX will remain unaltered
In the time since my last post, I found out that Irvine's library also has an StrLength function that I'm pretty sure is exactly what the second bullet requires. It is pasted below. I think my current goal is to see if it is possible to alter the StrLength function in order to accomplish the third bullet's task which is: "Your program must have a procedure that accepts the address of a string and returns through EAX the amount of "words" the string contains. For the purposes of this project, consider a "word" to be any non-whitespace characters that are bounded by whitespace, or by the beginning or ending of the string".
StrLength PROC
;
; OBSOLETE???
; Returns the length of a null-terminated string.
; Receives: EDX points to the string.
; Returns: EAX = string length.
; Last update: 6/9/05
;---------------------------------------------------------
push edx
mov eax,0 ; holds character count
L1: cmp BYTE PTR [edx],0 ; end of string?
je L2 ; yes: quit
inc edx ; no: point to next
inc eax ; add 1 to count
jmp L1
L2: pop edx
ret
StrLength ENDP
Currently, I have bullets 1-4 completed, but I'm stuck once again on bullet 5, which says the following: "Your program must have a main procedure that calls the input method, calls the other three methods
mentioned above, and reports the findings of those three methods. See the Sample Run" (I put a link to a picture of the Sample Run below). There isn't anything difficult about calling functions, but I have no idea how to display output, or put values from registers into the output message for that matter. Can anybody provide hints / tips on how to do this?
Picture of Sample Run: http://puu.sh/nsOat/92e5fe92c1.png
Current code below:
INCLUDE c:\irvine\irvine32.inc
INCLUDELIB c:\irvine\irvine32.lib
INCLUDELIB c:\masm32\lib\user32.lib
INCLUDELIB c:\masm32\lib\kernel32.lib
.data
theStringArray BYTE 256 dup(?)
prompt BYTE "Please enter a String: ",0
.CODE
main PROC
mov edx,offset theStringArray
mov ecx,sizeof theStringArray
call requestInput
call getStringLength
call getNumWords
call getNumVowels
exit
main ENDP
requestInput PROC
push edx
push ecx
mov edx,offset prompt
call WriteString
pop ecx
pop edx
call ReadString
ret
requestInput ENDP
getStringLength PROC
push edx
mov eax,0
L1: cmp BYTE PTR [edx],0
je L2
inc edx
inc eax
jmp L1
L2: pop edx
ret
getStringLength ENDP
getNumWords PROC
push edx
mov eax,0
L1: cmp BYTE PTR [edx],0
je L3
cmp BYTE PTR [edx]," "
je L2
inc edx
jmp L1
L2: inc edx
inc eax
jmp L1
L3: pop edx
ret
getNumWords ENDP
getNumVowels PROC
push edx
mov eax,0
L1: cmp BYTE PTR [edx],0
je L3
cmp BYTE PTR [edx],"a"
je L2
cmp BYTE PTR [edx],"A"
je L2
cmp BYTE PTR [edx],"e"
je L2
cmp BYTE PTR [edx],"E"
je L2
cmp BYTE PTR [edx],"i"
je L2
cmp BYTE PTR [edx],"I"
je L2
cmp BYTE PTR [edx],"o"
je L2
cmp BYTE PTR [edx],"O"
je L2
cmp BYTE PTR [edx],"u"
je L2
cmp BYTE PTR [edx],"U"
je L2
inc edx ; no: point to next
jmp L1
L2: inc edx
inc eax
jmp L1
L3: pop edx
ret
getNumVowels ENDP
END main