Joshua Ven Honoridez
Joshua Ven Honoridez

Reputation: 15

Implementation of conditional statement in x86 assembly

I would like to know how to implement this lines of code into x86 masm assembly:

    if (x >= 1 && x <= 100) {
        printsomething1();
    } else if (x >= 101 && x <= 200) {
        printsomething2();
    } else {
        printsomething3();
    }

Upvotes: 1

Views: 1821

Answers (2)

Brendan
Brendan

Reputation: 37232

I'd break it into contiguous ranges, (assuming x is unsigned) like:

  • x is 0, do printsomething3()
  • x is 1 to 100, do nothing printsomething1()
  • x is 101 to 200, do nothing printsomething2()
  • x is 201 or higher, do nothing printsomething3()

Then work from lowest to highest, like:

    ;eax = x;

    cmp eax,0
    je .printsomething3
    cmp eax,100
    jbe .printsomething1
    cmp eax,200
    jbe .printsomething2
    jmp .printsomething3

If the only difference is the string they print (and not the code they use to print it) I'd go one step further:

    mov esi,something3     ;esi = address of string if x is 0
    cmp eax,0
    je .print
    mov esi,something1     ;esi = address of string if x is 1 to 100
    cmp eax,100
    jbe .print
    mov esi,something2     ;esi = address of string if x is 101 to 200
    cmp eax,200
    jbe .print
    mov esi,something3     ;esi = address of string if x is 201 or higher
    jmp .print

Upvotes: 5

wallyk
wallyk

Reputation: 57774

If you have access to a decent C compiler, you can compile it into assembly language. For gcc use the -S flag:

gcc test.c -S

This creates the file test.s which contains the assembly language output which can be assembled and linked if needed.

For example, to make your code compile successfully, I rewrote it slightly to this:

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

void printsomething (int y)
{
    printf ("something %d", y);
}

void func (int x)
{
    if (x >= 1 && x <= 100)
        printsomething(1);
    else
    if (x >= 101  && x <= 200)
        printsomething(2);
    else
        printsomething(3);
}

int main (int argc, char **argv)
{
    int x = 0;
    if (argc > 1)
        x = atoi (argv [1]);
    return 0;
}

It compiles into this assembler:

    .file   "s.c"
    .text
    .section    .rodata
.LC0:
    .string "something %d"
    .text
    .globl  printsomething
    .type   printsomething, @function
printsomething:
.LFB5:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    subq    $16, %rsp
    movl    %edi, -4(%rbp)
    movl    -4(%rbp), %eax
    movl    %eax, %esi
    movl    $.LC0, %edi
    movl    $0, %eax
    call    printf
    nop
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE5:
    .size   printsomething, .-printsomething
    .globl  func
    .type   func, @function
func:
.LFB6:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    subq    $16, %rsp
    movl    %edi, -4(%rbp)
    cmpl    $0, -4(%rbp)
    jle .L3
    cmpl    $100, -4(%rbp)
    jg  .L3
    movl    $1, %edi
    call    printsomething
    jmp .L4
.L3:
    cmpl    $100, -4(%rbp)
    jle .L5
    cmpl    $200, -4(%rbp)
    jg  .L5
    movl    $2, %edi
    call    printsomething
    jmp .L4
.L5:
    movl    $3, %edi
    call    printsomething
.L4:
    nop
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE6:
    .size   func, .-func
    .globl  main
    .type   main, @function
main:
.LFB7:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    subq    $32, %rsp
    movl    %edi, -20(%rbp)
    movq    %rsi, -32(%rbp)
    movl    $0, -4(%rbp)
    cmpl    $1, -20(%rbp)
    jle .L7
    movq    -32(%rbp), %rax
    addq    $8, %rax
    movq    (%rax), %rax
    movq    %rax, %rdi
    call    atoi
    movl    %eax, -4(%rbp)
.L7:
    movl    $0, %eax
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE7:
    .size   main, .-main
    .ident  "GCC: (GNU) 7.3.1 20180712 (Red Hat 7.3.1-6)"
    .section    .note.GNU-stack,"",@progbits

Examine the func: part of it and you'll see how it sets up the comparisons with 1, 100, 101, etc.

Upvotes: 1

Related Questions