proc

  • Follow


hi
here i have an c programing proc that i want to write it in assembly
i think my assembly code isn't correct . if any one know how to
improve it please help me
int f (int a) { int x;  int y ;   char z[3];     y=z[1]+3;     return
y ; }
 1) i dont know how to set a parameter for my proc in assembly ?
2) is my code correct ?


..data

x db  ?
y db  ?
z db  3  dup (?)
y db  ?

..code
mov  ax,@data
mov  ds,ax
call   f


f  proc  far
   mov bx , offset z
   mov y ,bx
   add y , 3
   ret  y
f  endp
0
Reply nicole 1/14/2011 7:51:56 AM

In article  <e66f0050-1e98-4e1e-b3ce-866e4395d66a@g26g2000vbz.googlegroups.com>
           nicol.young20@nospicedham.gmail.com "nicole" writes:

> hi
> here i have an c programing proc that i want to write it in assembly
> i think my assembly code isn't correct . if any one know how to
> improve it please help me
> int f (int a) { int x;  int y ;   char z[3];     y=z[1]+3;     return
> y ; }

Your C function is rather suspect to begin with...

  int f (int a) /* parameter is not used in the function! */
  { 
    int x;      /* this is unused */
    int y;
    char z[3];  /* this is unintialised */

    y=z[1]+3;   /* this will give different results depending
                 * on whether 'char' is signed or not (given
                 * that 'z' had even been initialised)
                 */ 
    return y;
  }

> 1) i dont know how to set a parameter for my proc in assembly ?

Your asm code looks like 16 bit, so parameters are usually passed on 
the stack using the BP register as a stack frame pointer.  That said, 
it looks from your code as though you are not intending to call f() 
from a C program, so you can choose whatever way you like to pass in 
parameters and/or return a result.

> 2) is my code correct ?

Unfortunately not...

> .data
> 
> x db  ?
> y db  ?

In 16 bit code, x and y will be "words", so you need "dw"

> z db  3  dup (?)
> y db  ?

'y' has already been declared.

> .code
> mov  ax,@data
> mov  ds,ax
> call   f

You should do something here with the result from the call, but at the 
very least exit the program cleanly with a "ret" or (assuming MSDOS) 
something like

  mov ax, 4C00h
  int 21h

> f  proc  far

No need to make f() a far proc in such a tiny program, but not a big 
deal...

>    mov bx , offset z
>    mov y ,bx

Probably "mov y, [bx]" (though there might be an issue with operand 
sizes).

>    add y , 3
>    ret  y

"ret" does not mean the same thing as "return" in C; if you want to 
return a value you would normally put it in a register(s) that the 
caller knows about.  In 16 bit code, this is normally AX (or DX:AX for 
a 32 bit/long value) -- in your case, you might say

  mov ax, y
  ret

> f  endp

What you might find instructive is to write a small C program that 
contains a main() that calls f() and prints the result, and ask the 
compiler to generate the asm for you (the '-S' compiler switch is 
quite common to do this).  That way you should gain an insight into 
how functions are called, parameters are passed, and results are 
returned.

Pete
-- 
   "We have not inherited the earth from our ancestors,
    we have borrowed it from our descendants."
0
Reply pete 1/14/2011 8:23:37 PM


nicole wrote:
> hi
> here i have an c programing proc that i want to write it in assembly
> i think my assembly code isn't correct . if any one know how to
> improve it please help me
> int f (int a) { int x;  int y ;   char z[3];     y=z[1]+3;     return
> y ; }

I dunno... I am highly inexpert in C, but that doesn't make much sense 
to me. You're apparently passing the function "f" a parameter "a", but 
not using it. Instead you've got "local" (on the stack) variables "x" 
(unused), "y" (intended to hold the "result"), and the array "z" (used 
uninitialized!). This is going to return garbage! What am I missing?

>  1) i dont know how to set a parameter for my proc in assembly ?

"push", usually.

> 2) is my code correct ?

Not entirely. Pretty good approximation of the above, but...

> .data
> 
> x db  ?
> y db  ?
> z db  3  dup (?)
> y db  ?

You can't have two variables named "y"!!! Doesn't your assembler 
complain about this?

> .code
> mov  ax,@data
> mov  ds,ax

; push a ; to pass a parameter

> call   f

Okay, what happens when "f" returns? You need to at least exit cleanly! 
You may want to print your "result", or something, but you *must* exit! 
High level languages generate this code for you, but we gotta do it.

mov ax, 4C00h ; error-level zero
int 21h

> f  proc  far

What does "proc far" do for you? If you don't know, look it up.

>    mov bx , offset z

Okay. If your array were "local", as the C example(?), it wouldn't have 
an "offset" and we'd have to use "lea" to get its address, but with "z" 
in the data segment, "offset" is good.

>    mov y ,bx

But here you've got a problem. You defined "y" as a single byte, but bx 
is a 16-bit, two byte, register. Won't fit! I don't think you want the 
"offset" (address) of your array here anyway. "z[1]" would be a "char", 
no? Type-mismatch in C(?). Anyway, I think you want "[contents of 
memory]" here. "z[1]", or perhaps clearer, "[z + 1]" (I think Masm will 
accept either syntax - Nasm accepts only the latter). We can't move that 
directly into the variable "y" - memory-to-memory moves are not allowed. 
But we should be able to do:

mov al, [z + 1]

Then, we could do...

mov y, al

and this...

>    add y , 3

But we could as easily do:

add al, 3

>    ret  y

Well, no. "ret", in some of its forms, takes a parameter, but it's the 
number of parameters to remove from the stack - useful for "stdcall", 
but not here. You want just "ret" (or maybe "ret far", if you really 
want your function to be "far"). By convention, the "result" of a 
function is returned in ax. We've already got "z[1] + 3" in al... I 
suppose we should do "mov ah, 0" to make it an "int"(?). The C code said 
we were returning "int", no?

> f  endp

Again, I don't know what "endp" does. Look it up! (or don't use it)

We're still using uninitialized variables, so this is still going to 
return garbage. Honestly, I think you need a better C function to work from!

You probably want to pass a parameter that gets used for something - 
better, two parameters so you can note which is which! How 'bout an 
initialized array in your data segment, and pass its address and an 
"index" of the character/byte to return?

..data
z db 'abc'

..code
mov ax, @data
mov ds, ax

push 1 ; index
push offset z ; address of array
call f
add sp, 4 ; caller cleans up stack

int 29h ; print al

mov ax, 4C00h
int 21h

f: ; no tricks!
; set up "stack frame"
push bp
mov bp, sp
; sub sp, ??? if you need "local" variables

; preserve caller's regs - C expects this.
push bx
push si

mov bx, [bp + 4] ; address of array
mov si, [bp + 6] ; index
mov al, [bx + si]; "z[1]"

add al, 3 ; if you like

; restore caller's regs
pop si
pop bx

; destroy stack frame
mov sp, bp
pop bp

; or:
; leave

ret

That probably isn't passable Masm syntax, but maybe you can get it to 
work. Do you see how it accesses the parameters passed to the function? 
If it had been "far", the code segment as well as the offset would have 
been saved on the stack as the return address, and our parameters would 
be 2 farther up the stack - [bp + 6] and [bp + 8] (hope I remembered 
that right!)

Best,
Frank
0
Reply Frank 1/14/2011 8:57:52 PM

2 Replies
111 Views

(page loaded in 0.06 seconds)

Similiar Articles:













7/27/2012 9:34:50 AM


Reply: