Home > Enterprise >  how to increment value in assembly which was defined in C?
how to increment value in assembly which was defined in C?

Time:12-23

I want to combine c and assembly code.

I have the following C code:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

extern void _increment(unsigned short *x);

int main(int argc, char** argv)
{
    unsigned short x = 0;
    _increment(&x);
    printf("%d", x)
    return 0;
}

and the assembly(32bit NASM) code:

section .text

global _increment

_increment: 
    push ebx        

        mov bx, word [esp 8]    ;what is stored in bx here? the x address? 
        mov ax, [bx]            ;what is stored in ax here? the x value?

        ;add word [esp 8], 1 -> dosnt work 

        pop ebx             
        ret

section .data

if I execute this I get an Segmentation fault. Can someone explain what is stored in the registers/stack? and maybe how I can increment the Value and not the address of X?

CodePudding user response:

It's clear you understand how pointers work in general, the only mistake was the size of the pointer itself. On nearly all CPUs, the size of a pointer (not the size of the thing it points to) is going to equal the size of the instruction pointer register (often called PC for program counter on non-x86 architectures.) There are exceptions to this rule, but usually it's just going to match your hardware's default register size. Which is why, as you mentioned in the comments, that you only loaded half the pointer because you used bx as the destination of your load from the stack. In x86, the register operand that's not in brackets determines the number of bytes that will be read/written to memory. This is why you don't get an assembler error for mismatched operand size when you execute mov bx, word [esp 8] even though esp is 32-bit and bx is 16-bit; the right operand is 16-bit memory rather than a 32-bit register.

  • Related