Author Topic: Help with converting keyboard input into its hex output  (Read 15307 times)

Offline turtle13

  • Jr. Member
  • *
  • Posts: 73
Re: Help with converting keyboard input into its hex output
« Reply #15 on: August 21, 2017, 12:41:48 AM »
Instead of mud it's more like quicksand at this point  ;D

Here's my code so far incorporating your teachings, I'm a slow learner for sure. That's why they call me turtle. Actually just I call myself that.

I have commented out some lines that I think I may or may not need, your comments greatly appreciated.

Also when I try to compile with gcc I get error:

/usr/bin/ld:assign3_part2.asm: file format not recognized; treating as linker script
/usr/bin/ld:assign3_part2.asm:1: syntax error
collect2: error: ld returned 1 exit status


Code: [Select]
bits 32

global main

extern printf
extern exit

section .data
        ;test_str db 'Hello World!', 10, 0

section .text
main:
        push ebp                         ; save caller's frame pointer
        ;mov ebp, esp                    ; set up frame pointer
        push ebx
        push esi
        push edi     

        ; code
        mov ebx, [ebp + 12]
        mov esi, [ebx]
        push esi

        pop edi
        pop esi
        pop edx

        mov esp, ebp                    ; clean up stack frame
        pop ebp
        ret                           
       
        ;mov eax, [esp + 8]              ; this is where argv is on stack           
       
        ;mov eax, [eax + 12]             ; the envp parameters are stored here
       


        ;push test_str
        call printf
        pop eax

        xor eax, eax
        call exit
        push 0
        add esp, 4

The further I go the less I know!
« Last Edit: August 21, 2017, 12:43:50 AM by turtle13 »

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Help with converting keyboard input into its hex output
« Reply #16 on: August 21, 2017, 02:43:35 AM »
We used to say, "the more you learn, the more you forget. the more you forget, the less you know. why bother?" Or something like that. Actually, I forget what it was we used to say. It was a long time ago... but still proves the point...

Back to our clay tablet: On a 64-bit system, there is a possibility that the 32-bit C library is not installed. That's a game-ender. The solution is something like "aptget install gcc multilibs" or some such. Due to a poor choice of Linux distro (I think), I never had amy luck with that. I repeatedly wound up with a MS EULA, of all things. I said, "yeah yeah I agree" but still no go. It was my daughter's old machine, and shortly died entirely. I have a 64-bit machine, I just need to shovel off a space to put it. I am in no hurry!

However, the error message suggests a different problem. gcc, or ld, should never see the .asm file at all. First, assemble it with Nasm to an .o file, and then pass the .o file to gcc.
Code: [Select]
nasm -f elf32 assign3_part2.asm
gcc -m32 assign3_part2.o -o assign3_part2
Let us hope you have better luck with that.

Now... or whenever... you do need a commented-out line:
Code: [Select]
; told ya it was a good idea to do this...
; nasm -f elf32 assign3_part2.asm
; gcc -m32 assign3_part2.o -o assign3_part2
; ./assign3_part2 one two three

bits 32

global main

extern printf
extern exit

section .data
        ;test_str db 'Hello World!', 10, 0
        ; you don't use it yet, but you probably will want
        ; Nasm accepts C "escape sequences" if we
        ; use "back quotes"
        format db `%s\n\0`
        ; or
        ; format db "%s", 10, 0
section .text
main:
        push ebp                         ; save caller's frame pointer
        ; you do need this
        ; it is part of the normal "prolog"
        mov ebp, esp                    ; set up frame pointer

        push ebx
        push esi
        push edi     

        ; code
        mov ebx, [ebp + 12]
        mov esi, [ebx]
        push esi
        ; now of course you want:
        call printf
        pop eax ; or whatever

        pop edi
        pop esi
        ;pop edx same typo I made - I thought I fixed it
        pop ebx

        mov esp, ebp                    ; clean up stack frame
        pop ebp
        ret                           
        ; if you stop here, you should see the program name

In the part I've snipped, the idea was to push rhe parameter before calling "exit".

See if that gets you any closer...

Best,
Frank

Edit: tested, and works so far... on my 32-bit system


« Last Edit: August 21, 2017, 03:04:27 AM by Frank Kotler »

Offline turtle13

  • Jr. Member
  • *
  • Posts: 73
Re: Help with converting keyboard input into its hex output
« Reply #17 on: August 21, 2017, 06:20:38 AM »
Thanks for gcc help I was not paying attending and trying to compile the .asm file instead of .o which you pointed out.

My code so far, there must be something fundamental I am not understanding here. It returns the name of the program but nothing else.

Code: [Select]
bits 32

global main

extern printf
extern exit

section .data

        format db "%s", 10, 0

section .text
main:
        push ebp                        ; save caller's frame pointer
        mov ebp, esp                    ; set up frame pointer
       
        push ebx
        push esi
        push edi     

        mov ebx, [ebp + 12]
        mov esi, [ebx]
        push esi

        call printf
        pop eax

        pop edi
        pop esi
        pop ebx

        mov esp, ebp                    ; clean up stack frame
        pop ebp
        ret                           
       
        mov eax, [esp + 8]              ; this is where argv is on stack           
       
        pop eax

        mov eax, [eax + 12]             ; the envp parameters are stored here
       

        pop eax

        xor eax, eax
        call exit
        push 0
        add esp, 4
        ret

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Help with converting keyboard input into its hex output
« Reply #18 on: August 21, 2017, 04:28:36 PM »
Good progress getting it to compile.

All you ask for is argv[0]. At your first "ret", your program returns from "main". Code after that is never reached. To get the next argument, you'll want to add 4 to ebx. I do it as [ebx + edi] and "add edi, 4", but I think you could just "add ebx, 4". To know when to stop, check if esi is zero... or you could get "argc" off the stack. Don't try to use "loop" - printf trashes ecx! After printing args, get "envp" off the stack at [ebp + 16]. I think you'll find that it's just another 4 up the stack from where we were. The next time esi is zero, you're all done. Then "ret" or "exit" (not both).

On my machine, there are a lot of environment variables - much more than a screenful. You mught want to pipe it into "less".

Best,
Frank


Offline turtle13

  • Jr. Member
  • *
  • Posts: 73
Re: Help with converting keyboard input into its hex output
« Reply #19 on: August 21, 2017, 06:44:10 PM »
Getting segmentation fault at this point:

Code: [Select]
; nasm -f elf32 -g assign3_part2.asm -o assign3_part2.o
; gcc -m32 assign3_part2.o -o assign3_part2
; Prints argv and envp values for a C library function

bits 32

global main

extern printf
extern exit

section .data

        format db "%s", 10, 0

section .text
main:
        push ebp                        ; save caller's frame pointer
        mov ebp, esp                    ; set up frame pointer
       
        push ebx
        push esi
        push edi     

        mov ebx, [ebp + 12]
        mov esi, [ebx]
        push esi

        call printf

args:
       
        pop eax

        pop edi
        pop esi
        pop ebx

        mov esp, ebp                    ; clean up stack frame
        pop ebp                         
        add ebx, 4                      ; advance to next argv
        cmp esi, 0
        je done                         ; finishes if no more args   
       
        mov eax, [esp + 8]              ; this is where argv is on stack           
       
        pop eax

        mov eax, [eax + 12]             ; the envp parameters are stored here
       

        pop eax
        jmp args

done:

        ;ret       
        xor eax, eax
        call exit
        push 0
        add esp, 4

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Help with converting keyboard input into its hex output
« Reply #20 on: August 21, 2017, 07:42:56 PM »
Yeah, you're popping too much stuff. I haven't been clear...
Code: [Select]
; nasm -f elf32 -g assign3_part2.asm -o assign3_part2.o
; gcc -m32 assign3_part2.o -o assign3_part2
; Prints argv and envp values for a C library function

bits 32

global main

extern printf
extern exit

section .data

        format db "%s", 10, 0

section .text
main:
; prolog
        push ebp                        ; save caller's frame pointer
        mov ebp, esp                    ; set up frame pointer

; save regs that C wants preserved
        push ebx
        push esi
        push edi     

        mov ebx, [ebp + 12]

top:
        mov esi, [ebx]
   
        test esi, esi ; or cmp esi, 0
        jz done_with_args

        push esi
        push format ; might as well use it
        call printf
        add esp, 8 ; or pop two "dummy" regs

        add ebx, 4
        jmp top
done_with_args:

; do envp here - mov ebx, [ebp + 16], etc.

; get back regs C wants preserved
        pop edi
        pop esi
        pop ebx

; epilog
        mov esp, ebp                    ; clean up stack frame
        pop ebp                         
; "leave" does the same as these two lines

        ret ; or call exit

Some of your comments near the end of your code about where **argv and **envp are not correct.

Best,
Frank


Offline turtle13

  • Jr. Member
  • *
  • Posts: 73
Re: Help with converting keyboard input into its hex output
« Reply #21 on: August 22, 2017, 02:16:13 AM »
After getting some help today from my professor and doing a little research online, I have rewritten my code from the ground up. Still getting a seg fault, but I'm getting there:

Code: [Select]
bits 32

section .text
        global main

        extern printf


section .data
        format db "%s", 10, 0

main:

        add esp, 8                      ; argv[0] each stack frame 4 bytes (esp + 4 = argc)

argv_loop:

        cld                             ; clear the direction flag to increment
        lodsd                           ; pointer to string at esi is loaded into eax

        cmp eax, 0                      ; have we reached the end of argv[]?
        je envp_loop                    ; jump if yes
        push eax                        ; push parameter for printf
        push dword format               ; push the format for printf
        call printf                     ; print the argv[] parameter
        pop esi
        pop eax       
        add esp, 4
        jmp argv_loop

envp_loop:

        cld
        lodsd   
 
        cmp eax, 0                      ; have we reached end of envp[]?
        je done                         ; jump to done if yes
        push eax
        push dword format       
        call printf                     ; otherwise, print the envp value       
        pop esi
        pop eax       
        add esp, 4
        jmp envp_loop

done:
        mov ebx, 0                      ; exits program
        mov eax, 1
        int 0x80

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Help with converting keyboard input into its hex output
« Reply #22 on: August 22, 2017, 03:25:21 AM »
I'm afraid I've totally lost the plot. I can confirm that it segfaults. It appears to be in libc somewhere - it isn't in your code. Before the segfault, I see one environment variable.

I can see that your entire code is in "section .data". I can see that you use "lodsd" without initializing esi to anything useful. Beyond that, I'll have to study it some more. Honestly, I think your last attempt was a lot closer.

Best,
Frank


Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Help with converting keyboard input into its hex output
« Reply #23 on: August 22, 2017, 04:42:09 AM »
Well, I remain quite lost. After your call to printf, you pop esi. At this point, esi ought to point to your format string. This can't be right, can it? I have commented this out - both times. I have initialized esi to [esp], which "might" be right. Maybe. To my total astonishment, this seems to work. I really don't know why, but if it works it works.

Code: [Select]
bits 32

section .text
        global main

        extern printf


section .data
        format db "%s", 10, 0

section .text

main:

        add esp, 8                      ; argv[0] each stack frame 4 bytes (esp + 4 = argc)

    mov esi, [esp] ; point esi at... something

argv_loop:

        cld                             ; clear the direction flag to increment
        lodsd                           ; pointer to string at esi is loaded into eax

        cmp eax, 0                      ; have we reached the end of argv[]?
        je envp_loop                    ; jump if yes
        push eax                        ; push parameter for printf
        push dword format               ; push the format for printf
        call printf                     ; print the argv[] parameter
;        pop esi
        pop eax       
        add esp, 4
        jmp argv_loop

envp_loop:
        cld
        lodsd   
 
        cmp eax, 0                      ; have we reached end of envp[]?
        je done                         ; jump to done if yes
        push eax
        push dword format       
        call printf                     ; otherwise, print the envp value       
;        pop esi
        pop eax       
        add esp, 4
        jmp envp_loop

done:
        mov ebx, 0                      ; exits program
        mov eax, 1
        int 0x80

Baffled,
Frank


Offline turtle13

  • Jr. Member
  • *
  • Posts: 73
Re: Help with converting keyboard input into its hex output
« Reply #24 on: August 22, 2017, 05:38:35 AM »
Thank you mucho Baffled Frank and Best Frank, by removing the pop esi and putting the value of argv[0] (esp + 8) into esi and continuing with the code it is working great. Finally can turn this SOB in, and now on to the next assignment...

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Help with converting keyboard input into its hex output
« Reply #25 on: August 22, 2017, 04:12:43 PM »
I don't know why I didn't see this earlier. I think the "add esp, 8" threw me for a loop. You "can't do that". That trashes the return address from "main"! Of course if you're not returning from main, that's not a problem. Throwing away "argc" also - we don't need it. That puts us at "**argc" - right where we want to be. I've used "lodsd" before for much the same purpose.

If we skip the C startup code, from "_start:", there's no return address - we start with "argc" and then the arguments then a zero then the environment variables. You've got almost the same thing. So I shouldn't be surprised that it worked. That really is a better approach than what you were doing originally. Good job!

Best,
Frank