void scroll_framebuffer() {
  unsigned short *fb = ((unsigned short *)0x000B8000);
  int i;
  for (i = 0; i <= 80 * (25 - 1); ++i) {
    unsigned short symbol = fb[i + 80];
    fb[i] = symbol;
  }
  for (i = (80 * (25 - 1)); i < 80 * 25; ++i) {
    fb[i] = 0;
  }
}


x86 assembly (clang, -O0):
<scroll_framebuffer>:
push   %rbp
mov    %rsp,%rbp
mov    $0xb8000,%eax
mov    %rax,-0x8(%rbp)
movl   $0x0,-0xc(%rbp)
cmpl   $0x780,-0xc(%rbp)
jg     1154 <scroll_framebuffer+0x54>
mov    -0x8(%rbp),%rax
mov    -0xc(%rbp),%ecx
add    $0x50,%ecx
movslq %ecx,%rcx
mov    (%rax,%rcx,2),%ax
mov    %ax,-0xe(%rbp)
mov    -0xe(%rbp),%dx
mov    -0x8(%rbp),%rax
movslq -0xc(%rbp),%rcx
mov    %dx,(%rax,%rcx,2)
mov    -0xc(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xc(%rbp)
jmp    1114 <scroll_framebuffer+0x14>
movl   $0x780,-0xc(%rbp)
cmpl   $0x7d0,-0xc(%rbp)
jge    1184 <scroll_framebuffer+0x84>
mov    -0x8(%rbp),%rax
movslq -0xc(%rbp),%rcx
movw   $0x0,(%rax,%rcx,2)
mov    -0xc(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xc(%rbp)
jmp    115b <scroll_framebuffer+0x5b>
pop    %rbp
ret

x86 assembly (clang, -O2):
<scroll_framebuffer>:
mov    $0xb8110,%eax
xor    %ecx,%ecx
nopw   0x0(%rax,%rax,1)
movaps -0x70(%rax,%rcx,2),%xmm0
movaps -0x60(%rax,%rcx,2),%xmm1
movaps -0x50(%rax,%rcx,2),%xmm2
movaps -0x40(%rax,%rcx,2),%xmm3
movaps %xmm0,-0x110(%rax,%rcx,2)
ff
movaps %xmm1,-0x100(%rax,%rcx,2)
ff
movaps %xmm2,-0xf0(%rax,%rcx,2)
ff
movaps %xmm3,-0xe0(%rax,%rcx,2)
ff
movaps -0x30(%rax,%rcx,2),%xmm0
movaps -0x20(%rax,%rcx,2),%xmm1
movaps %xmm0,-0xd0(%rax,%rcx,2)
ff
movaps %xmm1,-0xc0(%rax,%rcx,2)
ff
movaps -0x10(%rax,%rcx,2),%xmm0
movaps (%rax,%rcx,2),%xmm1
movaps %xmm0,-0xb0(%rax,%rcx,2)
ff
movaps %xmm1,-0xa0(%rax,%rcx,2)
ff
add    $0x40,%rcx
cmp    $0x780,%rcx
jne    1110 <scroll_framebuffer+0x10>
movzwl 0xb8fa0,%eax
mov    %ax,0xb8f00
xorps  %xmm0,%xmm0
movaps %xmm0,0xb8f90
movaps %xmm0,0xb8f80
movaps %xmm0,0xb8f70
movaps %xmm0,0xb8f60
movaps %xmm0,0xb8f50
movaps %xmm0,0xb8f40
movaps %xmm0,0xb8f30
movaps %xmm0,0xb8f20
movaps %xmm0,0xb8f10
movaps %xmm0,0xb8f00
ret

LLVM IR (-O0):
define void @scroll_framebuffer() {
%1 = alloca i16*
%2 = alloca i32
%3 = alloca i16
store i16* inttoptr (i64 753664 to i16*), i16** %1
store i32 0, i32* %2
br label %4
4: ; preds = %19, %0
%5 = load i32, i32* %2
%6 = icmp sle i32 %5, 1920
br i1 %6, label %7, label %22
7: ; preds = %4
%8 = load i16*, i16** %1
%9 = load i32, i32* %2
%10 = add nsw i32 %9, 80
%11 = sext i32 %10 to i64
%12 = getelementptr inbounds i16, i16* %8, i64 %11
%13 = load i16, i16* %12
store i16 %13, i16* %3
%14 = load i16, i16* %3
%15 = load i16*, i16** %1
%16 = load i32, i32* %2
%17 = sext i32 %16 to i64
%18 = getelementptr inbounds i16, i16* %15, i64 %17
store i16 %14, i16* %18
br label %19
19: ; preds = %7
%20 = load i32, i32* %2
%21 = add nsw i32 %20, 1
store i32 %21, i32* %2
br label %4
22: ; preds = %4
store i32 1920, i32* %2
br label %23
23: ; preds = %31, %22
%24 = load i32, i32* %2
%25 = icmp slt i32 %24, 2000
br i1 %25, label %26, label %34
26: ; preds = %23
%27 = load i16*, i16** %1
%28 = load i32, i32* %2
%29 = sext i32 %28 to i64
%30 = getelementptr inbounds i16, i16* %27, i64 %29
store i16 0, i16* %30
br label %31
31: ; preds = %26
%32 = load i32, i32* %2
%33 = add nsw i32 %32, 1
store i32 %33, i32* %2
br label %23
34: ; preds = %23
ret void
}

LLVM IR (-O2):
define void @scroll_framebuffer() {
br label %1
1: ; preds = %1, %0
%2 = phi i64 [ 0, %0 ], [ %50, %1 ]
%3 = add nuw nsw i64 %2, 80
%4 = getelementptr inbounds i16, i16* inttoptr (i64 753664 to i16*), i64 %3
%5 = bitcast i16* %4 to <8 x i16>*
%6 = load <8 x i16>, <8 x i16>* %5
%7 = getelementptr inbounds i16, i16* %4, i64 8
%8 = bitcast i16* %7 to <8 x i16>*
%9 = load <8 x i16>, <8 x i16>* %8
%10 = getelementptr inbounds i16, i16* inttoptr (i64 753664 to i16*), i64 %2
%11 = bitcast i16* %10 to <8 x i16>*
store <8 x i16> %6, <8 x i16>* %11
%12 = getelementptr inbounds i16, i16* %10, i64 8
%13 = bitcast i16* %12 to <8 x i16>*
store <8 x i16> %9, <8 x i16>* %13
%14 = or i64 %2, 16
%15 = add nuw nsw i64 %2, 96
%16 = getelementptr inbounds i16, i16* inttoptr (i64 753664 to i16*), i64 %15
%17 = bitcast i16* %16 to <8 x i16>*
%18 = load <8 x i16>, <8 x i16>* %17
%19 = getelementptr inbounds i16, i16* %16, i64 8
%20 = bitcast i16* %19 to <8 x i16>*
%21 = load <8 x i16>, <8 x i16>* %20
%22 = getelementptr inbounds i16, i16* inttoptr (i64 753664 to i16*), i64 %14
%23 = bitcast i16* %22 to <8 x i16>*
store <8 x i16> %18, <8 x i16>* %23
%24 = getelementptr inbounds i16, i16* %22, i64 8
%25 = bitcast i16* %24 to <8 x i16>*
store <8 x i16> %21, <8 x i16>* %25
%26 = or i64 %2, 32
%27 = add nuw nsw i64 %2, 112
%28 = getelementptr inbounds i16, i16* inttoptr (i64 753664 to i16*), i64 %27
%29 = bitcast i16* %28 to <8 x i16>*
%30 = load <8 x i16>, <8 x i16>* %29
%31 = getelementptr inbounds i16, i16* %28, i64 8
%32 = bitcast i16* %31 to <8 x i16>*
%33 = load <8 x i16>, <8 x i16>* %32
%34 = getelementptr inbounds i16, i16* inttoptr (i64 753664 to i16*), i64 %26
%35 = bitcast i16* %34 to <8 x i16>*
store <8 x i16> %30, <8 x i16>* %35
%36 = getelementptr inbounds i16, i16* %34, i64 8
%37 = bitcast i16* %36 to <8 x i16>*
store <8 x i16> %33, <8 x i16>* %37
%38 = or i64 %2, 48
%39 = add nuw nsw i64 %2, 128
%40 = getelementptr inbounds i16, i16* inttoptr (i64 753664 to i16*), i64 %39
%41 = bitcast i16* %40 to <8 x i16>*
%42 = load <8 x i16>, <8 x i16>* %41
%43 = getelementptr inbounds i16, i16* %40, i64 8
%44 = bitcast i16* %43 to <8 x i16>*
%45 = load <8 x i16>, <8 x i16>* %44
%46 = getelementptr inbounds i16, i16* inttoptr (i64 753664 to i16*), i64 %38
%47 = bitcast i16* %46 to <8 x i16>*
store <8 x i16> %42, <8 x i16>* %47
%48 = getelementptr inbounds i16, i16* %46, i64 8
%49 = bitcast i16* %48 to <8 x i16>*
store <8 x i16> %45, <8 x i16>* %49
%50 = add nuw nsw i64 %2, 64
%51 = icmp eq i64 %50, 1920
br i1 %51, label %52, label %1
52: ; preds = %1
%53 = load i16, i16* inttoptr (i64 757664 to i16*)
store i16 %53, i16* inttoptr (i64 757504 to i16*)
ret void
}