Assembly Problem

Discussion in 'Programmer's Corner' started by maple23, Apr 23, 2008.

  1. maple23

    Thread Starter New Member

    Apr 23, 2008
    I have been working with assembly (TASM32) for a few months now and have ran into a problem which I cannot fix. Here's a working example written in C++ which needs to be converted to assembly.
    Code ( (Unknown Language)):
    2. #include <windows.h>
    4. int    main(){
    5.     char    *name_list[5] = {"Micheal", "Stefan", "Judy", "William", "Lora"};
    6.     for(int i = 0; i < 5; i++){
    7.         MessageBox(0, name_list[i], name_list[i], 0);
    8.     }
    9.     return 0;
    10. }[/i][/i]
    Here's the assembly version I've written. It goes through the five names fine, after the names, it brings up a message box with random characters.
    Code ( (Unknown Language)):
    1. .386
    2. .model flat
    4. EXTRN    MessageBoxA : PROC
    5. EXTRN    ExitProcess : PROC
    7. .DATA
    8.     dd ?            ; TASM gayness
    10. .CODE
    11. MAIN:
    12.     pushad
    13.     call    lblNames
    14.         db "Micheal", 0
    15.         db "Stefan", 0
    16.         db "Judy", 0
    17.         db "William", 0
    18.         db "Lora", 0
    20. lblNames:
    21.     pop    esi        ; esi = current name
    22.     push    5        ; 5 names
    23.     pop    ecx        ; ecx = counter
    25. lblNameLoop:
    26.     push    0
    27.     push    esi
    28.     push    esi
    29.     push    0
    30.     call    MessageBoxA
    32. lblNextChar:
    33.     lodsb
    34.     test    al, al
    35.     jnz    lblNextChar
    37.     pop    ecx
    38.     loop    lblNameLoop
    40.     popad
    42.     push    0
    43.     call    ExitProcess
    44. END    MAIN
    Does anyone know what the problem is, or have any suggestions for me? This seems much more complicated than it should be...

    Sorry for my English.

    Thank you,
    Stefan Kendrick
  2. Mark44

    Well-Known Member

    Nov 26, 2007
    What problems are you having with the code you show? Does it assemble without error? Can you link it without error?

    If you can get the code to assemble and link, your best friend is the debugger, probably called TDEBUG32. I haven't used the Borland product since their version 3.1 I think it was, but they worked well for me.

    Anyway, until I hear more from you, here are some things to think about...
    You can put the strings in the .DATA section, which is what it's for. It probably doesn't hurt anything to have them where they are, but it's something to think about.
    The first thing that happens is the pushad instruction, which I believe pushes the general purpose registers (EAX, EBX, ECX, EDX, ESI, EDI, EBP, ESP) onto the stack. The next thing that happens is the call to lblnames, which pops ESI right away. This won't do you any good, since you'll get whatever was in ESI when it was pushed. Your comment indicates that it should contain (the address of) the current name, but I don't see this happening. What will go into ESI will be whatever value was pushed last in pushad. (Off the top of my head I don't know what order the general registers are pushed.)
    Continuing on, I see that you push 5, and then pop ECX, which is reasonable since you want your loop to run 5 times, and ECX is used for a loop counter. Each time a loop instruction is executed, ECX is decremented. When ECX is zero the loop terminates.

    In lblNameLoop, I have no idea what you're doing when you push 0, push ESI twice, and then push 0 again. Yes, you need to push the arguments for the call to MessageBoxA on the stack, but you need to make sure that the right things are getting into ESI and the other registers before you do the push operations. The instruction you need is mov, which moves a value from memory to register, or memory to memory, or register to memory, and a few other combinations, but you can't use it to move data from one register to another.

    I'll quit here, but there are other problems. One thing you should do is take your C++ program and look at it in the debugger, in the disassembly window. That will show you how the compiler-generated code looks, and will give you some ideas on how to do things in assembly.