Реализация условного оператора в сборке x86 - PullRequest
0 голосов
/ 29 октября 2018

Я хотел бы знать, как внедрить эти строки кода в сборку x86 masm:

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

Ответы [ 2 ]

0 голосов
/ 29 октября 2018

Я бы разбил его на смежные диапазоны (при условии, что x без знака), например:

  • х равен 0, делайте printsomething3 ()
  • х - это от 1 до 100, ничего не делать1 ()
  • х - это от 101 до 200, ничего не делать2 ()
  • х равен 201 или выше, ничего не печатать3 ()

Затем работайте от низшего к высшему, как:

    ;eax = x;

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

Если единственное отличие - это строка, которую они печатают (а не код, который они используют для его печати), я бы пошел еще дальше:

    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
0 голосов
/ 29 октября 2018

Если у вас есть доступ к приличному компилятору C, вы можете скомпилировать его на языке ассемблера. Для gcc используйте флаг -S:

gcc test.c -S

Это создает файл test.s, который содержит выходные данные на языке ассемблера, которые могут быть собраны и связаны при необходимости.

Например, чтобы ваш код успешно компилировался, я немного переписал его так:

#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;
}

Он компилируется в этот ассемблер:

    .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

Изучите часть func:, и вы увидите, как она устанавливает сравнения с 1, 100, 101 и т. Д.

...