0

(I am not a native speaker of the English language, sorry for the grammatical errors)

I couldn't find any good tutorial about mixing c and assembly(please recommend me if you have one) and started to figure it out by myself. However I got stuck when I tried to combine file input/output in assembly with a c main file. The print function prints out some random garbage I think the problem can be found with the parameters. If needed inform me about best practices. Thank you.


/* main.c */

extern int createfile(char filename[], int premissions);
extern int openfile(char filename[], int mode, int premissions);
extern void writefile(int len, char * str, int fd);
extern void readfile(int fd, char * str,int bs);
extern void closefile(char fd);
extern void print(int len, char * str);

int main() {
    int fd = createfile("Hello world", 0777);
    char str[4] = "HOPE";
    writefile(4, str, fd);
    closefile(fd);
    fd = openfile("Hello world", 0, 0777);
    char bf[4];
    readfile(fd, bf, 4);
    print(4, bf);
    closefile(fd);
}


; file.asm

; Needed to use the functions in c
SECTION .TEXT
    GLOBAL createfile
    GLOBAL openfile
    GLOBAL writefile
    GLOBAL readfile
    GLOBAL updatefile
    GLOBAL closefile
    GLOBAL print

createfile:
    push ebp             ; Include arguments
    mov ebp, esp
    sub esp, 12          ; Making space for local arguments

    mov eax, 8           ; System call number (sys_write)
    mov ebx, [ebp + 8]   ; Filename         
    mov ecx, [ebp + 12]  ; File permissions
    int 0x80             ; Call kernel

    mov esp, ebp         ; Clean up
    pop ebp
    ret                  ; Return control

openfile:
    push ebp             ; Include arguments
    mov ebp, esp
    sub esp, 16          ; Making space for local arguments

    mov eax, 5           ; System call number (sys_write)
    mov ebx, [ebp + 8]   ; Filename         
    mov ecx, [ebp + 12]  ; File acces mode
    mov edx, [ebp + 16]  ; File premissions
    int 0x80             ; Call kernel

    mov esp, ebp         ; Clean up
    pop ebp
    ret                  ; Return control

writefile:
    push ebp             ; Include arguments
    mov ebp, esp
    sub esp, 16          ; Making space for local arguments

    mov edx, [ebp + 8]   ; Number of bytes
    mov ecx, [ebp + 12]  ; Message to write
    mov ebx, [ebp + 16]  ; File descriptor 
    mov eax, 4           ; System call number (sys_write)
    int 0x80             ; Call kernel

    mov esp, ebp         ; Clean up
    pop ebp
    ret                  ; Return control

readfile:
    push ebp             ; Include arguments
    mov ebp, esp
    sub esp, 16          ; Making space for local arguments

    mov eax, 3           ; System call number (sys_write)
    mov ebx, [ebp + 8]   ; File descriptor
    mov ecx, [ebp + 12]  ; Pointer input buffer
    mov edx, [ebp + 16]  ; Buffersize
    int 0x80             ; Call kernel

    mov esp, ebp         ; Clean up
    pop ebp
    ret                  ; Return control

updatefile:
    push ebp             ; Include arguments
    mov ebp, esp
    sub esp, 16          ; Making space for local arguments

    mov eax, 19          ; System call number (sys_write)
    mov ebx, [ebp + 8]   ; File descriptor
    mov ecx, [ebp + 12]  ; Offset value
    mov edx, [ebp + 16]  ; Reference to offset
    int 0x80             ; Call kernel

    mov esp, ebp    

closefile:
    push ebp             ; Include arguments
    mov ebp, esp
    sub esp, 8           ; Making space for local arguments

    mov eax, 6           ; System call number (sys_write)
    mov ebx, [ebp + 8]   ; File descriptor
    int 0x80             ; Call kernel

    mov esp, ebp         ; Clean up
    pop ebp
    ret                  ; Return control

print:
    push ebp             ; Include arguments
    mov ebp, esp
    sub esp, 16          ; Making space for local arguments

    mov edx, [ebp + 8]   ; Number of bytes
    mov ecx, [ebp + 12]  ; Message to write
    mov ebx, 1           ; File descriptor
    mov eax, 4           ; System call number (sys_write)
    int 0x80             ; Call kernel

    mov esp, ebp         ; Clean up
    pop ebp
    ret                  ; Return control

I use a intel processor and Arch linux is my os.

Too compile and run I use:
nasm -f elf32 file.asm
gcc -m32 -o bin.o main.c file.o
./bin
Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Tijmen
  • 1
  • 1
    `updatefile` misses `pop ebp; ret` If that is intentional, then you mess-up the stack. – Paul Ogilvie Jun 05 '20 at 11:17
  • More specifically, it tailcalls `closefile`, with the fd number as the first arg. Use `strace ./.bin` to trace system calls, and a debugger like GDB to single-step your code. It should be pretty easy to see what's going on when you know approximately where to look. – Peter Cordes Jun 05 '20 at 11:20
  • 1
    There is no need for any of your `sub esp` as there are no local variables. Though it doesn't hurt. – Paul Ogilvie Jun 05 '20 at 11:20
  • Oh also, EBX is call-preserved, but your functions destroy the caller's value (as part of the clunky 32-bit system-call ABI). push/pop it in your functions around the system call. That could explain weirdness for sure, especially if your GCC defaults to `-fpie`, which in 32-bit mode might pick EBX as the GOT base. – Peter Cordes Jun 05 '20 at 11:21
  • @PaulOgilvie: they're using `nasm -f elf32 file.asm` and `gcc -m32` so that's actually correct. `push ebp` wouldn't assemble in 64-bit mode. – Peter Cordes Jun 05 '20 at 11:23
  • @PeterCordes, are there more registers that should be preserved across calls? – Paul Ogilvie Jun 05 '20 at 11:23
  • 1
    @PaulOgilvie: yes, all the GP-integer regs except EAX, ECX, and EDX. [What registers must be preserved by an x86 function?](https://stackoverflow.com/q/9603003). Most everything else (mm, x/y/zmm regs, EFLAGS) are call-clobbered, but the x87 stack has to be empty, and DF=0. Also [What are the calling conventions for UNIX & Linux system calls on i386 and x86-64](https://stackoverflow.com/q/2535989) mentions the user-space function calling convention as well. – Peter Cordes Jun 05 '20 at 11:26
  • Closed as duplicates of 2 of the bugs I spotted. If there are more bugs, add debugging info to your question to make a better [mcve] of a single problem. Your whole entire program isn't very minimal, and you don't even show the actual output or any `strace` or `gdb` results. – Peter Cordes Jun 05 '20 at 11:30

0 Answers0