Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

376
Views
Calling Assembly code from C++

I'm trying to write my own I/O library, so the first step is just being able to output a character. So far, this only needs to work on Linux. I wrote what I believe to be a solid _putc: label in x86 (with Intel syntax), and I put it in "io.h", then called it from my main file, "test.cpp". Here's the contents of test.cpp:

#include "io.h"
extern void _putc(char) __asm__("_putc");
int main(int argc, char** argv){
    _putc('c');
    return 0;
}

and here's my io.h:

asm(
"\n.intel_syntax noprefix"
"\n.globl _putc"
"\n_putc:"
"\n\tpush [ebp]"
"\n\tmov ebp,esp"
"\n\tmov eax,4"
"\n\tmov ebx,0"
"\n\tmov ecx,[ebp+8]"
"\n\tmov edx,1"
"\n\tint 0x80"
"\n\tret"
"\n.att_syntax" ;return to g++'s at&t syntax
);

I'm developing this on a an x86_64 Linux operating system using G++

I'm using this to compile:

 g++ -o test test.cpp -Wall

When run it segfaults immediately. I think my problem is calling convention, but there's no way to be absolutely sure. I tried wrapping the assembly in a function (void _putc(char c)) and removing the global label, but that didn't help. I also tried pushing the contents of ebp instead of the stuff it points to, but then it wouldn't compile.

NOTE: This has to work with only the line #include io.h in the main file (I can move the extern void _putc(char) __asm__("_putc"); after this works), and it has to work with C++, not just C. Also, please don't lecture me about function definitions in a header file, that's just what I'm doing.

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

With 64-bit code you really need to consider using syscall instead of int 0x80. The system call uses a 64-bit convention and the system call numbers differ from int 0x80 in 32-bit code. You can get an idea of the 64-bit system calls in this table. The sys_writeand sys_read calls look like:

%rax  System call %rdi              %rsi             %rdx         %r10      %r8   %r9
0     sys_read    unsigned int fd   char *buf        size_t count         
1     sys_write   unsigned int fd   const char *buf  size_t count

You need to get acquainted with the System V 64-Linux ABI if you want to understand how parameters are passed in 64-bit Linux code. Among other things after a call is entered, you generally have to align the stack to a 16-byte boundary if you intend to call other functions or syscalls.

Your code also suffers from a flaw where you pass a character to sys_write. sys_write requires an address to a buffer that contains the character, not the character itself.

This is a code dump that would work:

asm(
"\n.intel_syntax noprefix"
"\n.globl _putc"
"\n_putc:"
"\n\tadd rsp, -8"   // Allocate space on the stack to store the character passed
                    // Also aligns stack back to 16-bye boundary 
                    // with return address already on stack
"\n\tmov [rsp],rdi" // Move the character passed in RDI to memory(stack) for sys_write
"\n\tmov eax,1"     // With 64-bit syscalls RAX = 1 for sys_write
"\n\txor edi,edi"   // 1st parameter to syscall is in RDX. FD = 0
"\n\tlea rsi,[rsp]" // We need to pass pointer to memory containing our char
"\n\tmov edx,1"     // RDX = 1 character to print. Could reuse EAX instead of 1 for src
"\n\tsyscall"       // Make syscall (using syscall instead of int 0x80 for 64-bit)

"\n\tadd rsp, 8"    // Restore stack to state right after function entry
"\n\tret"
"\n.att_syntax prefix" //return to g++'s at&t syntax
);
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!