Anybody remember any Assembly?

enlightenedby42

Supreme [H]ardness
Joined
Jan 19, 2005
Messages
4,412
This is making me crazy and I'm sure its something simple...

Taking an assembly class, using NASM. The assignment is to read a dat file that has some employee names, pay rates, and hours worked. Supposed to calculate pay with time and a half overtime if applicable. Have everything working, but it seems to be skipping through my "if-then" logic which applies the overtime if hrs>40. ie It just multiplies rate by hours no matter what. Anyone happen to know what I'm missing here? Jeezus this should NOT have been my third cs class. Quite a trial by fire. :) This has been making me crazy for like 8 hrs. now...Anyway...here's the code...it seems to be skipping past the section with the label "overtime"
Code:
%include "asm_io.inc"
extern printf
extern fopen
extern fclose
extern fscanf
segment .data
dec_pt db ".",0
fmt2   db "%02d",0
ioutfmt db "%15d",0
fname  db "pay.dat",0
mode   db "r",0
handle dd 0
rate   dd 0
hours  dd 0
total  dd 0
over   dd 0
ifmt   db "%s%d%d%d",0
ofmt   db "%-15s%5d.%02d%7d%5d.%02d",0
blank  db " ",0
x100   dd 100
h40    dd 40
ot2    dd 2
name   db "                ",0

segment .text
global _asm_main

_asm_main:
        enter 0,0
        pusha
        mov eax,mode
        push eax
        mov eax,fname
        push eax
        call fopen
        add esp,8
        mov [handle],eax
top:
        mov eax,total
        push eax
        mov eax,hours
        push eax
        mov eax,rate
        push eax
        mov eax,name
        push eax
        mov eax,ifmt
        push eax
        mov eax,[handle]
        push eax
        call fscanf
        add esp,24
        cmp eax,-1
        je near done
        mov eax,[hours]
        cmp eax,[h40]
        jl regular
overtime:
        mov eax,[rate]          ;move rate to eax
        imul dword [h40]        ;find pay for 40 hr
        mov [total],eax         ;move to total
        mov eax,[hours]         ;move hours to eax
        sub eax,[h40]           ;subtract 40 hours from total hours
        mov [over],eax          ;move overtime hours
        mov eax,[rate]          ;move pay rate to eax
        cdq
        idiv dword [ot2]        ;divide pay by 2
        add eax,[rate]          ;add result to regular pay
        imul dword [over]
        add [total],eax
        mov eax,[total]
        cdq
        idiv dword [x100]
        mov ebx,eax
        mov ecx,edx
regular:
        mov eax,[rate]
        imul dword [hours]
        cdq
        idiv dword [x100]
        mov ebx,eax
        mov ecx,edx
print:
        mov eax,[rate]
        cdq  ; need to init edx!
        idiv dword [x100]
        push ecx
        push ebx
        push dword [hours]
        push edx
        push eax
        push dword name
        push dword ofmt
        call printf
        add esp,28
        call print_nl
        jmp top
done:
        mov eax,[handle]
        push eax
        call fclose
        add esp,4
        popa
        leave
        mov eax,0
        ret
 
Could you post asm_io.inc so I can compile this? Im too lazy to link with the C functions myself. But just glancing through your code, you seem to be putting the values not the addresses of your data on the stack before calling fscanf. Surprises me that the thing didnt segfault when trying to access the data.

I didnt look through the calculation part, but I would assume that after calculating overtime you wouldnt want execution to fall through into regular, but maybe you do I didnt check.

If you give me the include file id like to find the problem as an excuse to play with nasm. My course used masm with a io library supplied by the book we used instead of using c libraries.

Edit: never mind of the fall through part, but if you could include the input file too that would be great. =)
 
After playing for a while I got it to compile, I dont think your using anything in your include file so I just deleted that line and linked the two obj files together. How to compile this is at the end for anyone interested. (first time I've ever linked two languages together, thought it was fun.)

Anyway, even after compiling your program I couldnt for the life of remember how to get the address of a variable. Nasm didnt like LEA and brackets just give you the offset from the data segment and not the whole address. (Well they will segfault anyway, couldnt figure out how to add data segment base address to it.)

But im sure your program just isnt calling fscanf correctly as the function needs the address of something to store the data from the file into. You might be able to get fscanf to return everything on the stack, but thats a crappy way to do it. If you remember how to get the full address of a variable in nasm please tell me cause it is driving me nuts. With that I could probably see if anything else is wrong with your program. (doubt it though)

Sorry for the crappily written reply. =)

C stub file to link with, added a print function for easyness. compile this with "cl.exe /c include.c"
Code:
#include <stdio.h>

void printtest(void)
{
	printf("test\n");
	return;
}

Then download nasm from http://nasm.sf.net and compile his program with "nasm.exe -f win32 test.asm" (Be sure to call C functions with prepended understroke thats added by compiler. So use _printf and _fopen etc) Now you can link the files together with link.exe "link.exe test.obj include.obj" and you will have a exe ready to go.
 
If I'm not terribly mistaken, doesn't referring to a register/variable by name without [ ] around it return the address, and not the value?

You're exactly right though, it is something falling through somehow. Can't for the life of me figure out what I did wrong though.

It cracks me up how easy this would be in a high level language. I'm kind of glad I'm doing this though, 'cuz I'm gonna be like a pig in shit when I get back to Java or C or something. Definately been an interesting experience, this class has.

In any case, thanks a lot for taking a look at it. I know this was a pretty obscure one. Gonna look at it again in the morning with less espresso and a good night's sleep. Problems like these always seem to be fixed by some sort of sudden divine epiphany don't they? That's exactly why I'm digging CS though. Quite a rush when you actually get the bastard to work.
 
yah, definetely make the most of your assembly class, it's nice to know for electronics and stuff like that. my assembly instructor had us program a PIC microcontroller to control a servo (which would be used to control a small airplane rudder) using input from a potentiometer. both the hardest and funnest project i've ever done, and it was all just really basic assembly. cool stuff, but apparently i didnt retain much of it cuz your code was completely lost on me :p
 
HAH! It was such a rediculously simple mistake. I forgot to jump past the other branch where it calculates pay without overtime. It was just falling through. Gotta love it...lol

Just thought I'd share. Thanks for the advice.
 
lol, I just recompiled everything from scratch today, I must of messed with the code or something as it compiles and runs fine. Anyhow brackets in masm mean get address and variables by themselves are values, so thats where that confusion on my part came from. (Nasm does things backwards)

But anyway, not changing anything other than what must be changed for me to link this with C object code I got the following output with the following input. Im too lazy to check if this in indeed correct, but knowing me I probably will later anyway.

Code:
input
	test1 10 32 100
	test2 20 42 200
	test3 30 45 300
output
	test1              0.10     32    3.20
	test2              0.20     42    8.40
	test3              0.30     45   13.50
 
enlightenedby42 said:
HAH! It was such a rediculously simple mistake. I forgot to jump past the other branch where it calculates pay without overtime. It was just falling through. Gotta love it...lol

Just thought I'd share. Thanks for the advice.

Posted too close to see this reply, thats what I thought originally, but later changed my mind thinking you were calculating overtime, then leaving whatever under 40 hours to be handled by the normal routine.
 
Lord of Shadows said:
Posted too close to see this reply, thats what I thought originally, but later changed my mind thinking you were calculating overtime, then leaving whatever under 40 hours to be handled by the normal routine.

Yeah, the idea was kind of like having to branches in an if-then that does the calculations completely independantly, but that would have streamlined things quite a bit. Was just one jmp instruction away from it working just fine. Anyway, again I thank you for taking the time to look at it man. Assembly's pretty fun. Real unforgiving, but fun nonetheless.
 
Well, now I have nasm on my system path. It is very similar to masm with intel syntax and such. Major difference in the use of brackets, but in other ways almost exactly the same. I also have a better understanding of linking different languages together, always knew the requirements but never actually did it. Not sure how much I helped out really, but I did learn a few things along the way. =)
 
Lord of Shadows said:
Well, now I have nasm on my system path. It is very similar to masm with intel syntax and such. Major difference in the use of brackets, but in other ways almost exactly the same. I also have a better understanding of linking different languages together, always knew the requirements but never actually did it. Not sure how much I helped out really, but I did learn a few things along the way. =)
Oh...uh...well...you're welcome then? lol
 
Back
Top