assuming a C function like

int f( int x )

what will be the address of variable x on the stack?? is it , , ,??

and in the case of

int f ( int y, int x )

what will be the addresses of x and y??
Posted on 2010-10-15 07:28:17 by ashken
It's been a long night, so forgive me if I don't get this exactly right, but ...

For most processors, the stack grows in the negative direction (decrementing), so once some data is placed on the stack (causing the esp to be adjusted in a negative direction), we can find the data at a positive offset of esp. If we have no stackframe, then the first input param is at esp+4 (since the return address is at esp+0)

For the x86 processor, most compilers will only use the ebp register for procedures which require a STACK FRAME - that means that the procedure has one or more LOCAL VARIABLES - otherwise we don't normally expect to see ebp being used.

In the cases where a stack frame is required, we'll normally see something like this:


MyStupidProcedure proc arg1:DWORD
LOCAL MyDumbVariable[16]:BYTE

push esp          ;preserve value of esp on entry to procedure (for the return address)
mov ebp,esp      ;we'll use ebp to access our stackframe (input params and any locals)
sub esp, 16      ;adjust esp to point PAST the locals so we dont trash anything on the stack

;do stuff in there
;example - we can safely push and pop since esp wont trash anything now
;example - first input param is now at ebp+8 since we pushed one dword onto the stack

pop esp            ;restore the old esp so we can return to caller correctly
ret
MyStupidProcedure endp


Hope this is useful!
Posted on 2010-10-15 08:21:25 by Homer
Ummm.... actually I don't think that is quite right...


MyStupidProcedure proc arg1:DWORD
LOCAL MyDumbVariable[16]:BYTE

; push esp          ;preserve value of esp on entry to procedure (for the return address)
; no, no, no...

push ebp          ; preserve caller's ebp - they're probably using it

mov ebp,esp      ;we'll use ebp to access our stackframe (input params and any locals)
sub esp, 16      ;adjust esp to point PAST the locals so we dont trash anything on the stack

;do stuff in there
;example - we can safely push and pop since esp wont trash anything now
;example - first input param is now at ebp+8 since we pushed one dword onto the stack

; pop esp            ;restore the old esp so we can return to caller correctly
; this would have popped from our "local variable" space, no?

mov esp, ebp      ; restore esp - "free" local variables
pop ebp              ; restore caller's ebp - now esp is what it was on entry

ret
MyStupidProcedure endp


I may not have this right, either. When we say "proc" and "endp", it generates some code (no? I avoid using 'em, myself...) so I may have done it twice...

Maybe helpful to look at the calling code...


; int f (int x)
push x
call f
add esp, 4
...


When we "push x", x is at . The "call" pushes the return address on the stack (not obvious unless we RTFM). So now x is at (when we arrive at "f:").

With two parameters...


; int f (int x, int y)
push y ; C pushes 'em right to left
push x
call f
add esp, 8


The called function "f" can look like:


; return address is at
mov ecx, ; x
mov edx, ; y
; do something with 'em
; mov eax, return value
ret


Notice that this doesn't do "sub esp, localsize". It is possible to use local variables without a stack frame, but it's a PITA to keep track of where our parameters are, and to restore esp (the return address *must* be the next thing on the stack when we come to "ret"!!!). So it is common to use ebp as a "stack frame pointer"...


; -> return address, x -> , y ->
push ebp ; save caller's ebp
; now x -> , etc
mov ebp, esp  ; ebp = esp - stack frame pointer
; now x -> , y ->
sub esp, localsize ; if we want local variables
; now x ->
; but x still at - ain't that handy?

; do something
; get return value in eax

mov esp, ebp ; now esp is what it was after the "push ebp"
pop ebp  ; and now esp -> return address, and caller's ebp is restored
ret


To further confuse the issue, a modern compiler (gcc, at least) doesn't actually use "push x", etc. It generates some more complicated - but faster - code... but it is equivalent...

Anyway, Ashken, the address of x (and y) depends on "when" - before the "call f", or after?

Are we confused yet? :)

Best,
Frank

Posted on 2010-10-15 14:05:00 by fbkotler

I may not have this right, either. When we say "proc" and "endp", it generates some code (no? I avoid using 'em, myself...) so I may have done it twice...


OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE
MyStupidProcedure proc arg1:DWORD
LOCAL MyDumbVariable[16]:BYTE

  push ebp          ; preserve caller's ebp - they're probably using it
  mov ebp, esp      ;we'll use ebp to access our stackframe (input params and any locals)
  sub esp, 16      ;adjust esp to point PAST the locals so we dont trash anything on the stack

  ;;----
  ;; Now, just to be clear: The 16 comes from the total size of all 'LOCAL' variables allocated,
  ;; so if we did a:
  ;;    LOCAL myVarA:DWORD
  ;;    LOCAL myVarB:WORD
  ;;    LOCAL myVarC:DWORD
  ;; Then we would subtract ESP by (SIZEOF(DWORD) +SIZEOF(WORD) +SIZEOF(DWORD))
  ;; or simply: sub esp, (4*3).... HOLD UP!!! Now why did I do that? SIZEOF(WORD) is 2 not 4.
  ;; The reason I do that is to keep things aligned on the stack and to prevent any possible stalls.
  ;; Get used to doing this, always round up to the next dword if you can.
  ;;--

  ;do stuff in there
  ;example - we can safely push and pop since esp wont trash anything now
  ;example - first input param is now at ebp+8 since we pushed one dword onto the stack

  ; pop esp            ;restore the old esp so we can return to caller correctly
  ; this would have popped from our "local variable" space, no?

  mov esp, ebp      ; restore esp - "free" local variables
  pop ebp              ; restore caller's ebp - now esp is what it was on entry
  ret

MyStupidProcedure endp
OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef


Frank, yea, PROC/ENDP generate stuff, but MASM works using internal macros which can be "turned off" by setting the option to a NONE (empty macro) then resetting the default macro when you've finished your procedure. Cool thing about that feature is, it still preforms the argument variable translation for you so the code is still easy to read, you just have to do the stack init/cleanup yourself.

;; demo.asm - JWASM Epilogue & Prologue Demo
;; Build With:
;; jwasm -elf -zcw -Fo=demo.o demo.asm && gcc -s -nostartfiles -o demo demo.o
.386
.model flat, C
option casemap:none

%include @Environ(JWASM_INC)/jwasm.inc

.code

OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE
Say PROC msg:DWORD

push ebp
mov ebp, esp

invoke puts, msg

leave
ret

Say ENDP
OPTION EPILOGUE:EpilogueDef
OPTION PROLOGUE:PrologueDef

main PROC
invoke Say, CTEXT("Hello, World!")
xor eax, eax
ret
main ENDP

_start:

call main
xor ebx, ebx
xor eax, ebx
xor ebx, eax
xor eax, ebx
inc eax
int 80h

end _start
Posted on 2010-10-15 15:22:02 by Synfire
Wot?

I hope that's not supposed to clarify things for a beginner! If we're going to provide a "fake crt0.o" (the C "startup files"), shouldn't we fix up the stack before calling main? And what's that stuff after main returns? What if main doesn't return zero?

I haven't got any "jwasm.inc" on my system. I can see that, for this program, it needs to include "extern puts"... anything else? (or does Masm/Jwasm spell it "extrn"?)

Anyway, maybe Ashken can tell us which assembler he's using (makes a difference in syntax) and what OS (makes a difference whether we spell it "main" or "_main"), and perhaps we can come up with a more "precise" example that better illustrates the question at hand.

Best,
Frank

Posted on 2010-10-15 17:31:52 by fbkotler

assuming a C function like

int f( int x )

what will be the address of variable x on the stack?? is it , , ,??


Assuming 32-bit machine -
However note that most C compilers generate a prologue for each function that performs the following:


push ebp
mov  ebp, esp


Thus you're most likely going to access your function parameters using ebp:

  mov eax,     ; get param X

Posted on 2010-10-15 18:00:27 by p1ranha
:lol:


I hope that's not supposed to clarify things for a beginner! If we're going to provide a "fake crt0.o" (the C "startup files"), shouldn't we fix up the stack before calling main? And what's that stuff after main returns? What if main doesn't return zero?


What do is just call an 'int main( void )' function I don't do any argument initialization stuff like that and let GCC know that I don't want any startup code. On return, anything can be returned, that's the point of that craziness after the 'call main'. Basically it just zeros ebx, swaps the values in ebx and eax (since eax will have our return value from the procedure) then increments eax (which should be zero after the swap). So I'm basically doing sys_exit(main()); so that whatever main returns gets returned to the system... just in my own awkward little way. :lol:


I haven't got any "jwasm.inc" on my system. I can see that, for this program, it needs to include "extern puts"... anything else? (or does Masm/Jwasm spell it "extrn"?)


Yea, sorry about that. Force of habbit. The jwasm.inc file is like a wrap-up of all the standard headers (stdio.inc/stdlib.inc/etc.) and my base.mac from my personal include set. The only thing I'm actually using out of it is the CTEXT macro and the prototype for puts.

;; demo.asm - JWASM Epilogue & Prologue Demo
;; Build With:
;; jwasm -elf -zcw -Fo=demo.o demo.asm && gcc -s -nostartfiles -o demo demo.o

.386
.model flat, C
option casemap:none

    CTEXT MACRO text:VARARG
    LOCAL x
        .CONST
        IFIDNI <text>,<>
            x DB 0
        ELSE
            x DB text, 0
        ENDIF
        .CODE
        EXITM <OFFSET x>
    ENDM
    puts proto c :DWORD

.code

OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE
Say PROC msg:DWORD

    push ebp
    mov ebp, esp

        invoke puts, msg

    leave
    ret

Say ENDP
OPTION EPILOGUE:EpilogueDef
OPTION PROLOGUE:PrologueDef

main PROC
    invoke Say, CTEXT("Hello, World!")
    xor eax, eax
    ret
main ENDP

_start:

    ;; -- Good Demo of Why Commenting is Important Follows......
    call main
    xor ebx, ebx  ; EBX := 0
    xor eax, ebx  ;
    xor ebx, eax  ;
    xor eax, ebx  ; EBX now holds the return value
    inc eax      ; SYS_exit
    int 80h

end _start
Posted on 2010-10-15 19:21:12 by Synfire
Okay, on the assumption that "more is better" (not always true), and keeping in mind that we're addressing a beginner question...


    ;; -- Good Demo of Why Commenting is Important Follows......
    call main
; suppose main returns 42...
    xor ebx, ebx  ; EBX := 0
; xor anything with itself = 0
    xor eax, ebx  ;
; eax still 42, ebx still 0
    xor ebx, eax  ;
; now ebx = 42 also
    xor eax, ebx  ; EBX now holds the return value
; and eax = 0, 'cause we xor something with itself!
; this is the part I didn't get, first time through
    inc eax      ; SYS_exit
; SYS_exit is 1
    int 80h
; this is for Linux, for those who don't know that.


But maybe what Ashken needs the comments on is:


OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE
Say PROC msg:DWORD
; this defines "msg" as ""


    push ebp
    mov ebp, esp

        invoke puts, msg
; this is a macro which expands into:
; push msg - that is, push
; call puts
; add esp, 4 ; "remove" one parameter from stack

    leave
; this is not a macro, but a real CPU instruction
; it does the same as:
; mov esp, ebp
; pop ebp
; (but does it in just one byte)

    ret

Say ENDP
OPTION EPILOGUE:EpilogueDef
OPTION PROLOGUE:PrologueDef


Get into "enter" while we're here? Naw... ask if you wanna know, Ashken.

Best,
Frank

Posted on 2010-10-15 21:38:37 by fbkotler
How about this...

OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE
SomeProc PROC arg1:DWORD, arg2:dword
LOCAL ddVar1:DWORD
LOCAL ddVar2:DWORD
  push ebp
  mov ebp, esp
  sub esp, (4*2)







Reference    Base Pointer Relative      Stack Pointer Relative
arg2EBP + 12ESP + 20
arg1EBP + 8ESP + 16
Ret AddrEBP + 4ESP + 12
Old EBPEBP + 0ESP + 8
ddVar1EBP - 4ESP + 4
ddVar2EBP - 8ESP + 0

   leave
  ret
SomeProc ENDP
OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef

Posted on 2010-10-16 03:04:25 by Synfire
Yeah! Now *that* answers the question! (P1ranha, too). I really thought that Homer made a typo, pushing esp where he meant ebp, and I got kinda sidetracked trying to clear that up...

You got it now, Ashken? (you still with us?)

Best,
Frank

Posted on 2010-10-16 04:20:10 by fbkotler
thanx guys! am getting some concepts but some no!.anyway i just want the basic stuff mostly on interfacing between assembly and C ie calling C routines in ASM and vice versa.am using Nasm and the GCC based DJGPP trying to get a simple "Hello world" program. i  tried this

NASM


;
;
;
segment .data
param db "%d",0

msg db "Hello world!",0

segment .bss
;
;
segment .text

global _start
extern _printf

_start:
push ebp
mov ebp,esp
sub esp,32
pusha
mov ecx,
mov edx,
push ecx
push edx

call _printf
pop edx
      pop ecx
popa
mov esp,ebp
pop ebp

;

and for C


int main()
{
  int p;
  p = start();
  return p;
}


i must be doing alot of things awfully i just got this error


C:\DOCUME~1\vini\Desktop\src\PCASM~1\prep>gcc -o print.asm print.c
print.c:7:2: warning: no newline at end of file
c:/djgpp/tmp/ccShjznm.o:print.c:(.text+0x1d): undefined reference to `_start'
collect2: ld returned 1 exit status



Any help!! please!
Posted on 2010-10-16 05:04:08 by ashken
ashken,

Wouldn't gcc -o print.asm use print.asm as output file name and overwrite it instead of compilation?

popa retrieves eax from stack too, probably clobbering start()'s return value.

And last, but not least: how start() is supposed to return back to its caller?
Posted on 2010-10-16 06:36:18 by baldr
Yeah... you've got a number of small problems, including the ones baldr mentions. They can be fixed.


;
;
;
segment .data
param db "%d",0
; this is to print an integer. use "%s" for a zero-terminated string.

msg db "Hello world!",0

segment .bss
;
;
segment .text

global _start
; the name "_start" threw me for a loop! In Linux, "_start" is the name known to ld (the linker) as the default entrypoint. It may be okay in DJGPP, I'm not certain. You might want to call it "_my_asm_function" or something...

extern _printf

_start:
push ebp
mov ebp,esp
sub esp,32
pusha
; The only registers you explicitly use (besides ebp, which you save and restore correctly) are ecx and edx. You're allowed to trash them both (C calling convention). So you don't need to do this at all. As baldr points out, the "popa" will trash whatever is in eax - which is the value you want to return!  Since you've reserved space for a local variable, that can be used to get around the problem. I'll show you, but I'd just not do "pusha" and "popa", if I were you. If you alter ebx, esi, or edi, you are expected to save and restore them (C calling convention). Since you don't...

; mov ecx,
; this loads the "" of memory - you want the address! Some assemblers use "offset" here, in Nasm syntax we just do:

        mov ecx, msg

; mov edx,
; same here:

        mov edx, param

push ecx    ; "msg" first
push edx    ; then "param"
; you could also have done:
        ; push msg
        ; push param

call _printf
      ; okay, printf returns number of items printed, as I recall. It'll be in eax.
pop edx
      pop ecx
      ; since we don't care about the old values of ecx and edx, another way to "balance the stack" (which you need to do - C calling convention)...
      ; sub esp, 4 * 2  ; four bytes per parameter, two parameters
      ; the two pops are fine here - not as good if you've got many parameters

        ; since we're about to trash eax, we can stash it in a local variable:
        ; mov , eax
popa
        ; mov eax,
        ; as I said, I'd just not pusha/popa, but that saves eax temporarily

mov esp,ebp
pop ebp
        ; and of course you need a
        ret ; !


Now, before we can invoke gcc, we have to assemble this with Nasm - gcc won't handle it.


nasm -f coff print.asm


That should produce "print.obj", if all goes well. Now gcc was complaining about the lack of a newline in print.c, so you may want to make sure that ends on a blank line, but otherwise I think it's okay. As baldr points out, the "-o" switch to gcc sets the output file name, so you don't want the .asm filename there!


gcc -o print.exe print.obj print.c


I think that should do it, barring typos, postos, and brainos. :) If not, pay close attention to the error messages. There's information in 'em (honest!).


C:\DOCUME~1\vini\Desktop\src\PCASM~1\prep>gcc -o print.asm print.c
print.c:7:2: warning: no newline at end of file


"PCASM~1", eh? Using Dr. Carter's stuff? The warning isn't too big a deal (although we should try to avoid 'em!). As mentioned, you don't want "-o print.asm"!


c:/djgpp/tmp/ccShjznm.o:print.c:(.text+0x1d): undefined reference to `_start'
collect2: ld returned 1 exit status


The undefined reference to "_start" is because you didn't assemble the .asm file to an .obj file and include it on the command line to gcc. The underscore tells me that djgpp uses an underscore on externals - I should have remembered that, but Linux doesn't, and I wasn't sure. And it tells me that "start" is probably going to be an okay name for your function. If it were a "known entrypoint", as it is in Linux, I would expect "already defined" instead of "undefined reference". I could be wrong...

You might think about giving your function a more descriptive name (I suppose "start" is what you're doing). Maybe different names for the .c and .asm files, too. I think gcc will handle "print.obj" and "print.c" alright, but you could wind up with "print.obj" overwriting the other "print.obj" if you're not careful. :)

I like names like "mything.asm" and "callmything.c". but the "~1" in your error messages reminds me that you're limited to 8.3 filenames in djgpp. See, I told you there was information in 'em! :)

If you can't get it working from that, get back to us with details...

Best,
Frank

Posted on 2010-10-16 08:50:39 by fbkotler
@ashken:

According to your first post you have made a question other people did many times before too which doesn't need to be answered, actually.
Why don't you simply RTFM of your compiler about procedure parameter handling?!
I recommend WATCOM, which contains not only a very versatile C/FORTRAN compiler for almost any 16/32bit PC OS, but contains also all documentation about standard procedure parameter calling/return/structures/values... handling and their bending.
Download it for free and go through the manuals like I did here: ftp.openwatcom.org
Posted on 2010-10-16 15:38:37 by TasmDev
BITS 32
EXTERN _printf
GLOBAL _SayHello
SECTION .text
_SayHello:
%define _arg1 EBP+8
  push ebp
  mov ebp, esp

      push dword [_arg1]
      push dword dbHelloWorld
      call _printf
      add esp, (4 * 2) ; Clean up stack after CDecl Call: (SizeOf(Dword) * ArgumentCount)

      ;; After a C Function you basically add up all the argument you pass then add that to esp to
      ;; correct the stack pointer. If you don't do this, it'll cause a segmentation fault when the function
      ;; returns.

  leave
  ret

SECTION .data
dbHelloWorld db " %d", 13, 10, 0


#include <stdio.h>

extern void SayIt( unsigned int );

int main( void )
{
  SayIt(1);
  SayIt(2);
  SayIt(3);
  return(0);
}


CC = gcc
AS = nasm

CFLAGS = -v -Wal
AFLAGS = -f coff

all: demo.exe
debug: demo.exe ; gdb ./demo.exe
demo.exe : demo.c SayHello.o ; $(CC) $(CFLAGS) main.c -o demo.exe SayHello.o
SayHello.o : SayHello.asm ; $(AS) $(AFLAGS) SayHello.asm -o SayHello.o


Use GNU Make to build these (they should do what you want) then run 'make debug'. Study what is going on in the debugger. Also, if you are getting used to intel syntax, I suggest modifying gdb to run in intel mode. Try the following .gdbinit script:

# .gdbinit - GDB Configuration File

define bpl
info breakpoints
end
document bpl
list breakpoints
end

define bp
break * $arg0
end
document bp
set a breakpoint on address
usage: bp addr
end

define bpc
clear $arg0
end
document bpc
clear breakpoint at function/address
usage: bpc addr
end

define bpe
enable $arg0
end
document bpe
enable breakpoint #
usage: bpe num
end

define bpd
disable $arg0
end
document bpd
disable breakpoint #
usage: bpd num
end

define bpt
tbreak $arg0
end
document bpt
set a temporary breakpoint on address
usage: bpt addr
end

define bpm
awatch $arg0
end
document bpm
set a read/write breakpoint on address
Usage: bpm addr
end

define syntax
    set disassembly-flavor $arg0
end
document syntax
sets the current assembly syntax
usage: syntax
end

define regs
    printf "\t--------------------------------\n"
    printf "\teax: 0x%08X\tebx: 0x%08X\n", $eax, $ebx
    printf "\tecx: 0x%08X\tedx: 0x%08X\n", $ecx, $edx
    printf "\tedi: 0x%08X\tesi: 0x%08X\n", $edi, $esi
    printf "\tesp: 0x%08X\tebp: 0x%08X\n", $esp, $ebp
    printf "\teip: 0x%08X\n", $eip
    printf "\t--------------------------------\n"
    printf "\tcs:  0x%04X\tds:  0x%04X\n", $cs, $ds
    printf "\tes:  0x%04X\tfs:  0x%04X\n", $es, $fs
    printf "\tgs:  0x%04X\tss:  0x%04X\n", $gs, $ss
    printf "\t--------------------------------\n"
    printf "\t\tODITSZ_A_P_C\n\t\t"
    if (($eflags >> 0xB) & 1)
        printf "1"
    else
        printf "0"
    end
    if (($eflags >> 0xA) & 1)
        printf "1"
    else
        printf "0"
    end
    if (($eflags >> 9) & 1)
        printf "1"
    else
        printf "0"
    end
    if (($eflags >> 8) & 1)
        printf "1"
    else
        printf "0"
    end
    if (($eflags >> 7) & 1)
        printf "1"
    else
        printf "0"
    end
    if (($eflags >> 6) & 1)
        printf "1"
    else
        printf "0"
    end
    if (($eflags >> 5) & 1)
        printf "1"
    else
        printf "0"
    end
    if (($eflags >> 4) & 1)
        printf "1"
    else
        printf "0"
    end
    if (($eflags >> 3) & 1)
        printf "1"
    else
        printf "0"
    end
    if (($eflags >> 2) & 1)
        printf "1"
    else
        printf "0"
    end
    if (($eflags >> 1) & 1)
        printf "1"
    else
        printf "0"
    end
    if ($eflags & 1)
        printf "1"
    else
        printf "0"
    end
    printf " = 0x%08X\n", $eflags
end
document regs
displays the cpu registers
end

define proc
    info stack
    info frame
    info args
    info locals
end
document proc
displays a lot of information about the current procedure
end

define procs
    info functions
end
document procs
list all procedures in current process
end

define stack
    info stack
end
document stack
displays the call stack
end

define vars
    info variables
end
document vars
display the variables in the current process
end

define libs
    info sharedlibrary
end
document libs
display shared libraries linked into the target
end

define sigs
    info signals
end
document sigs
display signal actions for target
end

define threads
    info threads
end
document threads
display threads in target
end

define dasm
    disassemble $arg0
end
document dasm
disassemble code at address/label
usage: dasm
end

define start
    tbreak _start
    run
end
document start
run program; break on _start
end

define init
    tbreak _init
    run
end
document init
run program; break on _init
end

define main
    tbreak main
    run
end
document main
run program; break on _main
end

define lsmain
    tbreak __libc_start_main
    run
endm
document lsmain
run program; break on __libc_start_main
end

# Asm Simulations

define tcf
    if ( $eflags & 1 )
        set $eflags = $eflags &~ 1
    else
        set $eflags = $eflags | 1
    end
end
document tcf
toggle carry flag
end

define tpf
    if ( ($eflags >> 2) & 1 )
        set $eflags = $eflags &~ 0x4
    else
        set $eflags = $eflags | 0x4
    end
end
document tpf
toggle parity flag
end

define taf
    if ( ($eflags >> 4) & 1)
        set $eflags = $eflags &~ 0x10
    else
        set $eflags = $eflags | 0x10
    end
end
document taf
toggle auxiliary flag
end

define tzf
    if ( ($eflags >> 6) & 1 )
        set $eflags = $eflags &~ 0x40
    else
        set $eflags = $eflags | 0x40
    end
end
document tzf
toggle zero flag
end

define tsf
    if ( ($eflags >> 7) & 1 )
        set $eflags = $eflags &~ 0x80
    else
        set $eflags = $eflags | 0x80
    end
end
document tsf
toggle sign flag
end

define ttf
    if ( ($eflags >> 8) & 1 )
        set $eflags = $eflags &~ 0x100
    else
        set $eflags = $eflags | 0x100
    end
end
document ttf
toggle trap flag
end

define tif
    if ( ($eflags >> 9) & 1 )
        set $eflags = $eflags &~ 0x200
    else
        set $eflags = $eflags | 0x200
    end
end
document tif
toggle interrupt flag
end

define tdf
    if ( ($eflags >> 0xA) & 1 )
        set $eflags = $eflags &~ 0x400
    else
        set $eflags = $eflags | 0x400
    end
end
document tdf
toggle direction flag
end

define tof
    if ( ($eflags >> 0xB) & 1 )
        set $eflags = $eflags &~ 0x800
    else
        set $eflags = $eflags | 0x800
    end
end
document tof
toggle overflow flag
end

define pb
    set * (unsigned char *) $arg0 = $arg1
end
document pb
patch byte at address to value
usage: pb addr val
end

define pw
    set * (unsigned short int *) $arg0 = $arg1
end
document pw
patch word at address to value
usage: pw addr val
end

define pd
    set * (unsigned long int *) $arg0 = $arg1
end
document pd
patch dword at address to value
usage: pd addr val
end

# configuration defaults
set disassembly-flavor intel
set prompt \033[36m\033[39m\n:  \b


I'm sure if you play around with GDB and the source, (and re-read some of these posts) you'll definitely get whats going on. You're almost there man! Hang in there. :)

Regards,
Bryant Keller
Posted on 2010-10-16 15:55:02 by Synfire
@ Frank, Homer and all the guys who have spent their precious time to help me out, thank you guys.you have given me what i wanted, i asked for a sandwich and you gave me just.your cutting edge solutions have solved my particular problem.Despite the fact that you knew compiler manuals existed, you didn't RTFM me and for that, maximum RESPECT!!!

oh! as for my first code which has lots of errors. i build it and it gave me a segmentation fault.

Microsoft Windows XP
(C) Copyright 1985-2001 Microsoft Corp.

C:\Documents and Settings\vini\Desktop\src\PC ASM\prep>print
Exiting due to signal SIGSEGV
General Protection Fault at eip=00006666
eax=48006425 ebx=00000000 ecx=00000011 edx=48006425 esi=00000054 edi=0000f588
ebp=0008f4e0 esp=0008e0bc program=C:\DOCUME~1\VINI\DESKTOP\SRC\PCASM~1\PREP\PRIN
T.EXE
cs: sel=01a7  base=02980000  limit=0009ffff
ds: sel=01af  base=02980000  limit=0009ffff
es: sel=01af  base=02980000  limit=0009ffff
fs: sel=017f  base=000057a0  limit=0000ffff
gs: sel=01bf  base=00000000  limit=0010ffff
ss: sel=01af  base=02980000  limit=0009ffff
App stack: [0008f588..0000f588]  Exceptn stack: [0000f4e8..0000d5a8]

Call frame traceback EIPs:
 0x00006666
 0x000031d6
 0x000015fd
 0x00001631
 0x00002dd8

C:\DOCUME~1\vini\Desktop\src\PCASM~1\prep>
Posted on 2010-10-16 16:18:45 by ashken
Just a few notes about your previous code....

segment .data

param db "%s",0 ; FIXED: %d is for integers, %s is for strings.
msg db "Hello world!",0

;; This isn't needed, you're not using a BSS section.
;segment .bss

segment .text

global _Entry
extern _printf

;; I'm not comfortable with this name, Lets change it to Entry
;_start:
_Entry:
push ebp
mov ebp,esp
;; Why do you allocate local variables at all?
;; You're not using any. Again, unneeded.
;sub esp,32

pusha

mov ecx, msg ; FIXED: We want the ADDRESS of the label, not the contents of the memory.
mov edx, param ; FIXED: We want the ADDRESS of the label, not the contents of the memory.
push ecx
push edx
call _printf
pop edx
pop ecx
;; This could easily be done with ADD ESP, (4 * 2)

popa

mov esp,ebp
pop ebp

;; FIXED: You are missing a RETurn here.
ret


Read the comments, there are a few places where things could have gone wrong, most likely the "FIXED" sections. I've made a few other modifications simply because I don't feel comfortable re-releasing the code without pointing out the issues with them. :p
Posted on 2010-10-16 16:45:30 by Synfire
Just on inspection... "unresolved external _SayIt"... (since the global function in the .asm file is called "_SayHello"...) :) The fix is obvious. Nice example, as it shows passing a parameter, which we weren't doing. The ".gdbinit" should be a big help!

TasmDev, why do you think Watcom is superior to gcc? Oh, I know - Tasm won't produce COFF. Easily fixed - http://www.nasm.us :) If you try it, Ashken, trailing underscores, not leading... Nice compiler, but a little "oddball".

SIGSEGV at 0x00006666 - jeez, it's the number of the beast on steroids! :) Almost certainly failure to "clean up" the stack properly somewhere, I would guess... Lack of the "ret" would do it, also. If you can't fix it, post the exact code that produced it.

As for RTFM, excellent advice! Puts *me* to sleep, though... :)

Best,
Frank

Posted on 2010-10-16 19:56:42 by fbkotler
I'm going to have to get sp00k to install an "asshat counter" on the forum for me so I can keep track of how many times I've built something that worked fine, then made a last minute change (like modifying the name of a procedure or removing a macro) that has completely fubar the source. lmfao  8) Thanks for the catch man. The "SayIt"'s should definitely be "SayHello"'s, lol.
Posted on 2010-10-16 21:13:42 by Synfire