БДЗ ver 0306
.pdfint: is_int_int,\ char: is_int_char,\ short: is_int_short,\ long: is_int_long,\
unsigned int: is_int_unsint,\ default: is_int_not\
)(a)
int is_int_int(int a){return 1;} int is_int_char(char a){return 1;} int is_int_short(short a){return 1;} int is_int_long(long a){return 1;}
int is_int_unsint(unsigned int a){return 1;} int is_int_not(){return 0;}
//specifier!
#define fc(x) _Generic((x),\ int:"%d",\
long:"%ld",\
float:"%f",\
double:"%lf",\
char:"%c",\
char*:"%s",\
void*:"%p"\
)
void main(){ int a = 33;
float b = 23.2; double c = 90.2; char* d = "lele"; void* ptr = &a;
print_value(a); print_value(b); print_value(c); print_value(d); print_value(ptr);
printf("%f\n", max(5.1, 6.4));
char e = 'A'; printf("%d\n", is_int(a)); printf("%d\n", is_int(c)); printf("%d\n", is_int(e));
printf(fc(a),a);
printf(fc(b),b);
printf(fc(c),c);
printf(fc(d),d);
printf(fc(e),e);
}
#88 ====================================================================разобраться с тайпоф и генериком
gcc -std=c2x main.c -o main #define swap(a, b) do {\
typeof(a) temp = (a);\
(a)= (b);\
(b)= temp;\
}while(0)
#89
.section .text
.global _start
_start:
ПЛИС Стр.21
movl $1, %eax movl $42, %ebx int $0x80
movl — 4 байта (32 бита), movq — 8 байт (64 бита). movl также обнуляет старшие 32 бита приёмника.
eax — младшие 32 бита регистра rax. Запись в eax очищает старшие 32 бита rax.
#90
.globl _start
.data
message: .asciz "Doshik Morozov IVT-23!\n" # текст выводимого сообщения
.text _start:
movq $message, %rsi |
# в RSI - адрес строки |
movq $1, %rdi |
# в RDI - дексриптор вывода в стандартный поток (консоль) |
movq $34, %rdx |
# в RDX - длина строки |
movq $1, %rax |
# в RAX - номер функции для вывода в поток |
syscall |
# вызываем функцию Linux |
movq $60, %rax |
|
syscall |
|
#91 |
|
.section .data |
|
var: |
|
.quad 42 |
|
.section .text |
|
.global _start |
|
_start: |
|
lea var(%rip), %rax |
|
mov (%rax), %rdi |
|
mov $60, %rax |
|
syscall |
|
lea вычисляет адрес, но НЕ обращается к памяти по этому адресу. Просто помещает вычисленный адрес в регистр.
Берет текущее значение регистра rip (указатель на следующую инструкцию) и прибавляет к нему смещение var.
Ассемблер и линковщик заменяют var на относительное смещение от текущей инструкции до метки var.
Результат — абсолютный адрес переменной var в памяти.
#92
.global _start
.data
mes:
.ascii "equal\n"
len |
= . - mes |
|
|
|
.text |
|
|
_start: |
|
|
|
|
movq |
$5, %rax |
|
|
cmp |
$5, %rax |
|
|
jne N_EQ |
|
|
|
movq |
$1, %rax |
#системный вызов write |
|
movq |
$1, %rdi |
#stdout типа |
ПЛИС Стр.22
lea |
|
mes(%rip), %rsi #адрес строки для вывода |
|
movq |
|
$len, %rdx |
#кладем длину строки |
syscall |
|
|
|
N_EQ: |
|
|
|
movq |
|
$60, %rax |
#вызов exit(60) |
syscall |
|
|
|
#93 |
|
|
|
.global _start |
|
|
|
.data |
|
|
|
mes_eq: |
|
|
|
.ascii "equal\n" |
#сообщение равно |
||
len_eq = . - mes_eq |
|
||
mes_neq: |
|
|
|
.ascii "not equal\n" |
#сообщение не равно |
||
len_neq = . - mes_neq |
|
||
.text |
|
|
|
_start: |
|
|
|
movq |
|
$0, %rbx |
#задвигаем в rbx ноль |
cmp |
|
$5, %rbx |
|
jne N_EQ |
|
|
|
movq |
|
$1, %rax |
#задвигаем в rax сообщение для вывода |
movq |
|
$1, %rdi |
|
lea |
|
mes_eq(%rip), %rsi |
|
movq |
|
$len_eq, %rdx |
|
syscall |
|
#после каждого вывода надо сискол делать |
|
N_EQ: |
|
|
|
movq |
|
$1, %rax |
|
movq |
|
$1, %rdi |
|
lea |
|
mes_neq(%rip), %rsi |
|
movq |
|
$len_neq, %rdx |
|
syscall |
|
|
|
incq |
|
%rbx |
#ЗДЕСЬ +1 ДЕЛАЕМ К rbx |
cmp |
|
$5, %rbx |
|
jne N_EQ |
|
#ВОТ ТУТ ЦИКЛ ПОЛУЧАЕТСЯ |
|
movq |
|
$1, %rax |
|
movq |
|
$1, %rdi |
|
lea |
|
mes_eq(%rip), %rsi |
|
movq |
|
$len_eq, %rdx |
|
syscall |
|
|
|
mov |
|
$60, %rax |
|
mov |
|
$0, %rdi |
|
syscall |
|
|
|
#94 |
|
|
|
.section .text |
|
|
|
.global _start |
|
|
|
_start: |
|
|
|
movq |
$1, |
%rax |
|
pushq |
%rax |
|
|
movq |
$2, %rax |
|
|
pushq |
%rax |
|
|
movq |
$3, %rax |
|
|
ПЛИС Стр.23
pushq |
%rax |
|
movq |
$4, %rax |
|
pushq |
%rax |
|
movq |
$5, %rax |
|
pushq |
%rax |
|
movq |
$6, %rax |
|
pushq |
%rax |
|
movq |
$7, %rax |
|
pushq |
%rax |
|
movq |
$8, %rax |
|
pushq |
%rax |
|
movq |
$9, %rax |
|
pushq |
%rax |
|
movq |
$10, %rax |
|
pushq |
%rax |
|
popq |
%rax |
# 10 |
popq |
%rax |
# 9 |
popq |
%rax |
# 8 |
popq |
%rax |
# 7 |
popq |
%rax |
# 6 |
popq |
%rax |
# 5 |
popq |
%rax |
# 4 |
popq |
%rax |
# 3 |
popq |
%rax |
# 2 |
popq |
%rax |
# 1 |
mov $60, %rax mov %rbx, %rdi syscall
#95
.section .text
.global _start
_start:
# Кладём два числа на стек mov $10, %rax
push %rax mov $2, %rax push %rax
pop %rax pop %rbx
sub %rax, %rbx |
#сначала что вычитаем, потом откуда вычитаем |
# Выход с кодом = rbx mov $60, %rax
mov %rbx, %rdi syscall
#96
.section .text
.global _start
func:
push %rbp
mov %rsp, %rbp
mov 16(%rbp), %rax mov 24(%rbp), %rcx mov 32(%rbp), %rbx add %rax, %rbx
add %rcx, %rbx
ПЛИС Стр.24
pop %rbp ret
_start:
mov $7, %rax push %rax mov $5, %rax push %rax mov $10, %rax push %rax
call func
add $16, %rsp mov $60, %rax mov %rbx, %rdi syscall
#97 ez gg #98 ez gg #99 ez gg #100 ez gg
УРАААААААААААААААААААААААААААААААААААААААААААААААААААААААААААААААААААААААААААААААААААААА
ПЛИС Стр.25
