Scanf/Printf functions in Assembly

Discussion in 'Mac Programming' started by SAEinSDSU, Apr 1, 2010.

  1. SAEinSDSU macrumors newbie

    Joined:
    Feb 17, 2010
    #1
    I am confused on how to write a print and or scan function from C language in Assembly language. I looked through my book and couldnt find anything on the subject...am i just missing the concept or is there a trick to this? For example an assembly code for taking a Char input from the keyboard and then printing that Char out. I am using I386 Architecture for my assembly language. Please any help or hints would be much appreciated.
     
  2. CylonGlitch macrumors 68030

    CylonGlitch

    Joined:
    Jul 7, 2009
    Location:
    SoCal
    #2
    Here is the thing, Assembly language is just one step away from machine language; thus if you want the application to do something you have to write it yourself. The BIOS of the computer used to support some of the functions such as writing out characters to the screen, but then the screen was simple and easy to use (ascii value)(color). In todays market system design you really still need to make IO calls to the driver (if you can get one) or program your own API.

    There is a good reason why most people don't write things in assembly language any more (for PC's). Embedded systems do a good job with assembly and that is where it is mostly used.

    In the old dos days the screen was mapped to 0xB8000 (If I remember correctly) thus to write ASCII to the screen it would be like this :

    MOV AX, 0B00h
    PUSH AX
    POP DS
    MOV DX, 8000h ; Start at the upper left location on the screen
    MOV AH, <ASCII>
    MOV AL, <COLOR>
    MOV DS:[DX], AX
    INC DX ; move to the next position on the screen.

    This would write the ASCII character to the screen with the given color -- how you pass the variables is up to you also.

    (NOTE: Again, I haven't written 8086 assembly in years, so I may have confused it with another assembly, so don't expect it to compile.)
     
  3. Catfish_Man macrumors 68030

    Catfish_Man

    Joined:
    Sep 13, 2001
    Location:
    Portland, OR
    #3
    I would just call the libc scan/print functions from your asm.
     
  4. notjustjay macrumors 603

    notjustjay

    Joined:
    Sep 19, 2003
    Location:
    Canada, eh?
    #4
    Way back when I learned it (in school), we used INT 21h function calls, but I don't know if that's still (ever?) the preferred way to do it.
     
  5. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #5
    What is your book?

    I looked through your past posts, and I don't see anything that says what your book is, although I could have missed it.


    All reading from streams or files eventually calls the read() function, described in the man page 'man 2 read'. Likewise, all writing eventually calls the write() function; 'man 2 write'.

    Both read() and write() use file-descriptors, which are small positive integers representing an open byte-stream. See any book on the fundamentals of Posix-type OSes.

    If you want to know what the assembly language for read() or write() consists of, I suggest setting a breakpoint on the function, then disassembling the code. Or you could disassemble the function from its dylib (e.g. the 'otool' command can do this).

    There is no universal implementation of read() or write(), or any of the other C functions described in section 2 of the man pages. That's because different OSes implement primitive operations in different ways. The relevant standard (C99, Posix, etc.) specifies the API, i.e. what the function name and args are. It does not specify how any given function is to be implemented. As a result, it is not uncommon for internal implementations to vary significantly at the assembly-language level.


    When I first read your post I thought you were asking about varargs functions, because both printf() and scanf() are varargs functions. That's a completely different question than what the system calls for read or write are, so I hope I haven't guessed wrong above.

    If you really are asking about varargs functions, then that is something defined by the compiler. You should look in the <stdarg.h> header file, and also create test-cases and see what code the compiler generates.
     
  6. gnasher729 macrumors P6

    gnasher729

    Joined:
    Nov 25, 2005
    #6
    1. Start XCode.
    2. Write a function that does what you want in C.
    3. Choose Build -> Show Assembly Code.

    But please tell us what you are actually trying to achieve. Trying to print things from assembly language is just plain stupid and pointless. Learning how to read assembly language can be useful at times (when you are debugging and your program doesn't do what you think it should do then looking at the assembler code will tell you what your program really does - sometimes it's not what you think it does). Learning the gcc inline assembler feature and how to use it can be useful in some rare cases - google for "gcc documentation".
     
  7. CylonGlitch macrumors 68030

    CylonGlitch

    Joined:
    Jul 7, 2009
    Location:
    SoCal
    #7
    Yeah, I wasn't 100% clear on what he was asking, seemed like he was asking if Assembly has built in functions to do things like scanf and printf. But right, you could use the C language API's and just access them directly. BUT remember that they don't use the standard C calling convention, I believe that they use the standard Pascal calling convention because of the variable number of arguments. Both methods are well documented online.
     
  8. Mac Player macrumors regular

    Joined:
    Jan 19, 2006
    #8
    Hi!

    Let me start by saying that printf/scanf are extremely complicated and ugly functions, you can get the C source code for both here (libc). These functions end up calling the read and write which make a syscall. Printing chars via a syscall is about the lowest you can get on Mac OS. Beware however that the syscall interface is poorly documented and is subject to changes between point releases of Mac OS, so my recommendation is to just call the libc functions.

    Here is a 64 bit example for putc:
    Code:
    	.text
    .globl _main
    _main:
    	pushq	%rbp
    	movq	%rsp, %rbp	
    	movq	___stdoutp@GOTPCREL(%rip), %rax
    	movq	(%rax), %rsi
    	movl	$50, %edi
    	call	_putc
    	movl	$1, %edi
    	call	_exit
    	ret
    
    
    Assemble with,

    Code:
    as <name>.s -o <name>.o
    
    and link with,

    Code:
    ld -lc -o <name> <name>.o /usr/lib/crt1.o
    
     
  9. noexcuse4you macrumors newbie

    Joined:
    Feb 25, 2010
    #9
    We're not writing the scanf and printf functions ourselves. We are merely writing a function that calls the scanf and printf functions from within assembly.

    for example,

    int getNumber()
    {
    int a;
    scanf("%d", &a);
    return(a);
    }
     
  10. noexcuse4you macrumors newbie

    Joined:
    Feb 25, 2010
    #10
    Did you watch Ozturk's online lecture? He explains how to do it.

    Also, XCode doesn't like ".section .data" I have no clue how to make it work as there is little documentation online. I had to switch over to Eclipse on my PC to get his example to work.
     
  11. Mac Player macrumors regular

    Joined:
    Jan 19, 2006
    #11
    Which assembly code are you guys trying to assemble/link ?
     
  12. gnasher729 macrumors P6

    gnasher729

    Joined:
    Nov 25, 2005
    #12
    There is no such thing as "standard Pascal calling convention" anymore. printf and scanf will use the standard C calling conventions. These calling conventions are rather complex, and even more complex when you use variable number of arguments, and it gets horrendous when you mix in 64 bit and XMM, but it is all the standard C calling conventions.
     
  13. Sydde macrumors 68020

    Sydde

    Joined:
    Aug 17, 2009
    #13
    I believe you have that backwards. As I recall, the Pascal calling convention used on Classic Mac OS pushes arguments left-to-right (from the perspective of the function declaration) with space for a return value (for functions) reserved at the bottom (before the first argument) and the caller expects a clean-up stack. The C standard is almost exactly the opposite, except the return value is typically expected in a register (like eax or gpr2). Hence, Pascal is not suitable for a variable argument count in stack-based argument passing. (On PPC, at least in Classic, I believe they relied heavily on registers for argument passing.)
     

Share This Page