News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

print and eax

Started by jsolco, May 29, 2005, 12:08:07 AM

Previous topic - Next topic

jsolco

Sorry for the newb question, but what exactly does the print function do to eax? When I store a number in eax and then do a print chr$(13,10) before printing the value of eax, the value of eax is changed.

thanks for any help

jsolco

Actually, I have an even more basic problem. I can't even seem to write a simple program that asks for 2 integer inputs, adds them together, and prints them out!

mov eax, sval(input("Number 1: "))
mov ecx, sval(input("Number 2: "))
add ecx, eax
print str$(ecx)

The right value doesn't come out. Help?

MichaelW

The MASM32 library uses the same register preservation convention as the Windows API functions: EBX, EDI, and ESI (and EBP) are preserved, and EAX, ECX, and EDX are not. The second statement is overwriting the value in EAX. You can avoid this by preserving EAX on the stack, or by moving the value into one of the registers that are preserved (other than EBP).
eschew obfuscation

Mark Jones

Hello and welcome to the group.

Try not to get discouraged. Assembler might be some cryptic stuff in the beginning, but once you get the hang of it, it's actually quite nice. :)

First it's best to think of the basic syntax in MASM as != explicitly "BASIC" - STR$, CHR$, INT$, those are all macros in MASM and not fundamental functions - so they may not work exactly as they do in BASIC. In BASIC you don't have to worry about EAX being overwritten, but in MASM, you do.

There are many ways to accomplish console addition. I think the problem you're having is that the macros are overwriting the registers you want to use so the ADD instruction is never getting the correct values. edit: Michael beat me to it. :wink

The only way to determine this is to parse the code in a debugger. Do you have a good Win32 debugger such as OllyDbg? It is very helpful to stick a NOP in the code where you want to see what is happening, compile it, then open the program with Olly and press CTRL-F, NOP, Enter, F2, F9. Code execution will then halt at the NOP and you can check the registers and memory offsets for the correct contents (use F8/F7 to follow over/into calls.)

Is this a homework problem or just experimentation?
"To deny our impulses... foolish; to revel in them, chaos." MCJ 2003.08

jsolco

Thanks for all the helpĀ  :lol good to know which registers are definitely preservedĀ  :U

I learned assembly for the M68000 processor before, if you can believe that they actually still teach that. I just want to learn assembly for x86s, cuz that's so much more useful, in my opinion. This is purely a personal interest, not for school or anything.

I'll try out OllyDbg, since I don't know what good debugger there is in the MS Visual Studio 6.0 suite.

thanks again

GregL

learning_masm,

Hello, welcome to the group. Before you go looking for other debuggers, in my opinion you already have the best debugger for MASM in MS Visual Studio 6.0. To try it out, assemble with /Zi, link with /DEBUG, load the exe into Visual Studio and debug away.

Greg

Vortex

Hi learning_masm,

This one works:


.386
.model flat, stdcall
option casemap :none

include \masm32\include\windows.inc
include \masm32\include\masm32.inc
include \masm32\include\kernel32.inc
include \masm32\macros\macros.asm

includelib \masm32\lib\masm32.lib
includelib \masm32\lib\kernel32.lib

.code

start:

    push    esi
    mov     esi, sval(input("Number 1: "))
    mov     eax, sval(input("Number 2: "))
    add     esi, eax
    print   str$(esi)
    pop     esi
    invoke  ExitProcess,0

END start

Mark Jones


.386                        ; 80386 requirement
.model flat, stdcall        ; 32-bit code
option casemap:none         ; case sensitive

include windows.inc
include kernel32.inc
include masm32.inc
include shlwapi.inc
include c:\masm32\macros\macros.asm

includelib kernel32.lib
includelib masm32.lib
includelib shlwapi.lib

.data?
num1    dd  ?               ; first input buffer
num2    dd  ?               ; second input buffer
num3    dd  ?               ; "add" result buffer
num4    dd  ?               ; "sub"
num5    dd  ?               ; "imul"
num6    dd  ?               ; "idiv"
num7    dd  ?               ; "idiv" remainder

.code
main:

    print chr$(" Console signed-integer test by MCJ 2005 - press enter to exit.")
begin:
    mov eax, input(13,10,13,10," Enter first number: ")
    invoke StrToInt,eax     ; convert string to integer
    mov num1, eax           ; copy integer into num1 dword offset
    test eax,eax            ; if any input number is a zero,
    jz bye                  ; exit (divide by zero will crash the app)

    mov eax, input(" Enter second number: ")
    invoke StrToInt,eax     ; invoked results always returned in eax
    mov num2, eax           ; necessary to save values this way because
    test eax,eax            ; StrToInt overwrites eax,ecx, and edx
    jz bye
                           
_add:
    mov ecx, num1           ; load our number VALUES into ecx and
    mov edx, num2           ; edx - see ASMINTRO.HLP about dereferencing
    add ecx, edx            ; add edx to ecx, hex result in ecx
    mov num3, ecx           ; save result in num3 dword offset
   
    print chr$(13,10,"  ADD result: ")
    print str$(num1)
    print chr$(" + ")
    print str$(num2)
    print chr$(" = ")
    print str$(num3)

_sub:
    mov ecx, num1           ;
    mov edx, num2           ;
    sub ecx, edx            ; subtract edx from ecx, result in ecx
    mov num4, ecx           ;
   
    print chr$(13,10,"  SUB result: ")
    print str$(num1)
    print chr$(" - ")
    print str$(num2)
    print chr$(" = ")
    print str$(num4)

_mul:
    mov eax, num1           ;
    mov edx, num2           ;
    imul eax, edx           ; signed multiply eax & edx, result in eax
    mov num5, eax           ;
   
    print chr$(13,10," IMUL result: ")
    print str$(num1)
    print chr$(" * ")
    print str$(num2)
    print chr$(" = ")
    print str$(num5)

_div:
    mov eax, num1           ; load registers, imul uses eax
    mov ecx, num2           ;
    mov edx, 0              ; clear edx!
    idiv ecx                ; signed divide eax / ecx
    mov num6, eax           ; save quotient
    mov num7, edx           ; save remainder
   
    print chr$(13,10," IDIV result: ")
    print str$(num1)
    print chr$(" / ")
    print str$(num2)
    print chr$(" = ")
    print str$(num6)
    print chr$(" R: ")
    print str$(num7)

    jmp begin               ; start over

bye:
    invoke ExitProcess,0    ; exit gracefully

end main

[attachment deleted by admin]
"To deny our impulses... foolish; to revel in them, chaos." MCJ 2003.08

jsolco

ah thanks. Yes, the MS studio debugger seems pretty handy.

lol. Well, thanks for the codes.

brixton

Ollydbg is a great debugger/disassembler.  Try w32dasm also  :thumbu
If you love somebody, set them free.
If they return, they were always yours. If they don't, they never were..