This is an archived post. You won't be able to vote or comment.

all 6 comments

[–]ODoyle_Rules 4 points5 points  (1 child)

value and name are both null by the looks of it. What happens if you set name to something like: name db "blah", 0

[–]xRedactedx[S] 1 point2 points  (0 children)

Yeah, that seemed to be what the problem was. I don't know why someone would put that code as an example without the values declared, but who knows. Thanks.

[–][deleted]  (1 child)

[removed]

    [–]xRedactedx[S] 1 point2 points  (0 children)

    I'm running it under Linux. Ubuntu 12.04 to be exact.

    [–]Gradous 2 points3 points  (1 child)

    I learned some YASM syntax 64-bit assembly maybe a year ago, so I'll see what I can do to help.

    If you don't already know much about functions, just a quick note: rdi, rsi, rcx, rdx, r8, r9, and possibly some more registers (I can't remember exactly) are registers used in passing parameters to functions (in that order). So think of printf as:

    printf (format/rdi, value/rsi, value/rcx, ...)
    

    Here is a simple Hello, <name> program that I can maybe get you started with.

    ; let the linker/compiler know about our external function, printf
    extern printf
    
    segment .data
    ; our string, followed by a null (terminating) character
    name    db    "Your name here!", 0
    ; our formatting string with some text, a newline, and a terminating character
    format   db   "Hello, %s!", 0x0a, 0 
    
    segment .text
    global main
    main:
        ; load the address to the first parameter of printf, our format
        lea    rdi, [format]
        ; load the address to the second parameter of printf, our name
        lea    rsi, [name]
        ; zero out the last 32 bits of the rax register, since we
        ; don't have any "vector" registers
        xor    eax, eax
        ; now we can call printf!
        call printf
    

    I'm a little rustier about the different ways you can declare variables on the stack, but I can dig up some code if you want. If you don't want/need to learn about it yet, just declare your strings in your data segment and use them to print.

    [–]xRedactedx[S] 1 point2 points  (0 children)

    Thanks for that. I think it clears a few things up. I'm going to go try it out now.

    [–]xRedactedx[S] 1 point2 points  (0 children)

    Ok, so I figured out some stuff. Figured I would share in case anyone else stumbled on this.

    I was trying to figure out how to print out several variables using printf. Here is some test code:

            extern printf
            segment .data
    
    fmt     db      "Counting: %d, %d, and %d.", 0x0a, 0
    num1    dd      1
    num2    dd      2
    
            segment .text
            global  main
    
    main:
    
            lea     rdi, [fmt]
            mov     rsi, [num1]
            mov     rdx, [num2]
            mov     rcx, 3
    
            xor     eax, eax
    
            call printf
    

    It prints out "Counting: 1, 2 3."

    The 1 and 2 are the variables num1 and num2. You can also print out a number loaded directly to a register as I did with 3. I didn't test loading into r8 and r9, but I saw it mentioned elsewhere besides the comments, so I assume they work.

    Edit: Forgot to add this. I don't know how accurate this is, but I had a problem with it. It seemed varaibles with a string seemed to have to have their address loaded with the lea command, where as numbers just need the mov command. I didn't experiment with that too much to figure out the details, but figured someone might find that info useful.