組合語言 mov指令,暫存器,定址

2021-10-11 02:38:12 字數 4762 閱讀 4605

馮諾依曼計算機,將計算機分為5大部件:運算器,控制器,儲存器,輸入裝置,輸出裝置。運算器和控制器共同執行指令。指令和資料一樣,儲存為二進位制資料。運算器和控制器共同組成cpu,cpu執行機器指令,也就是二進位制數。機器指令難於閱讀,編寫。所以人們用英語單詞來表示機器語言,這種方式被稱為組合語言。

用組合語言程式設計就是在和立即數,暫存器,內存在打交道。

暫存器有8個,eax,ebx,ecx,edx,edi,esi,ebp,esp。

記憶體有不同的定址方式,下面會詳細說明。

複製位元組資料。

mov指令有兩個運算元,源運算元和目標運算元。源運算元可以為立即數,暫存器,記憶體位址,目的運算元可以為暫存器,記憶體位址。兩者不能同時為記憶體位址。

所有5種變化:

movb $1,%eax

movb $1,list

movb %al,%cl

movb %al,list

movb list,%al

.section .data

list:.byte 0,0,0,0,0,0,0,0,0,0,0,0,0

.section .text

.global main

main:

pushl %ebp

movl %esp,%ebp

movb $'h',list

movb $'e',list+1

movb $'l',list+2

movb $'l',lis+3

movb $'o',list+4

movb $',',list+5

movb $'w',list+6

movb $'o',list+7

movb $'r',list+8

movb $'l',list+9

movb $'d',list+10

movb $'\n',list+11

movb $'\0',list+12

pushl $list

call printf

addl $4,%esp

movl %ebp,%esp

popl %ebp

ret

movb $'h',list是直接定址,**用數字給出了記憶體位址,下面的movb都是直接定址。list在彙編和鏈結後會是乙個記憶體位址,list+1在list的後乙個位元組。

gcc hello.s -o hello

./hello

輸出:hello,world

除了用直接定址,還可以暫存器間接定址

.section .data

list:.byte 0,0,0,0,0,0,0,0,0,0,0,0,0

.section .text

.global main

main:

pushl %ebp

movl %esp,%ebp

movl $list,%eax

movl $'h',(%eax)

addl $1,%eax

movl $'e',(%eax)

addl $1,%eax

movl $'l',(%eax)

addl $1,%eax

movl $'l',(%eax)

addl $1,%eax

movl $'o',(%eax)

addl $1,%eax

movl $',',(%eax)

addl $1,%eax

movl $'w',(%eax)

addl $1,%eax

movl $'o',(%eax)

addl $1,%eax

movl $'r',(%eax)

addl $1,%eax

movl $'l',(%eax)

addl $1,%eax

movl $'d',(%eax)

addl $1,%eax

movl $'\n',(%eax)

addl $1,%eax

movl $'\0',(%eax)

addl $1,%eax

pushl $list

call printf

addl $4,%esp

movl %ebp,%esp

popl %ebp

ret

記憶體定址的一般公式是:address(暫存器1,暫存器2,比例因子)。比例因子可以為1,2,4,8。記憶體位址為address+暫存器1的值+暫存器2的值*比例因子。其中的元素可以省略。直接定址省略了(暫存器1,暫存器2,比例因子)。暫存器間接定址省略了address,暫存器2,比例因子。

下面為基址定址

.section .data

list:.byte 0,0,0,0,0,0,0

.section .text

.global main

main:

pushl %ebp

movl %esp,%ebp

movl $0,%eax

movl $'h',list(%eax)

addl $1,%eax

movl $'e',list(%eax)

addl $1,%eax

movl $'l',list(%eax)

addl $1,%eax

movl $'l',list(%eax)

addl $1,%eax

movl $'0',list(%eax)

addl $1,%eax

movl $'\n',list(%eax)

addl $1,%eax

movl $'\0',list(%eax)

addl $1,%eax

pushl $list

call printf

addl $4,%esp

movl %ebp,%esp

popl %ebp

ret

基址加變址

.section .data

list:.byte 0,0,0,0

.section .text

.global main

main:

pushl %ebp

movl %esp,%ebp

movl $list,%eax

movl $0,%edx

movl $'a',(%eax,%edx)

addl $1,%edx

movl $'b',(%eax,%edx)

addl $1,%edx

movl $'c',(%eax,%edx)

addl $1,%edx

pushl $list

call printf

addl $4,%esp

movl %ebp,%esp

popl %ebp

ret

複製四位元組資料

其他定址方式

.section .rodata

.lc0:.string "%d %d %d\n"

.section .data

list:.int 0,0,0

.section .text

.global main

main:

pushl %ebp

movl %esp,%ebp

movl $2,%eax

movl $200,list(,%eax,4) //變址比例因子定址

movl $list,%eax

movl $1,%edx

movl $100,(%eax,%edx,4) //基址加變址定址

movl $0,%eax

movl $0,%edx

movl $1,list(%eax,%edx,4) //基址加變址定址

pushl list+8

pushl list+4

pushl list

pushl $.lc0

call printf

addl $16,%esp

movl %ebp,%esp

popl %ebp

ret

gcc hello.s -o hello

./hello

輸出:1 100 200

總結一下記憶體定址方式

1000

1000(%eax)

1000(,%edx,4)

1000(%eax,%edx)

1000(%eax,%edx,4)

(%eax)

(%eax,%edx)

(%eax,%edx,4)

(,%edx,4)

複製2個位元組

.section .rodata

.lc0:.string "%x \n"

.section .data

list .short 0,0

.section .text

.global main

main:

pushl %ebp

movl %esp,%ebp

movw $0x1122,list

movw $0x3344,list+2

pushl list

pushl $.lc0

call printf

addl $8,%esp

movl %ebp,%esp

popl %ebp

ret

彙編暫存器,mov指令 2021 3 13

即 ax,bx,cx,dx,sp,bp,si,di,ip,flag,cs,ds,ss,es 共 14 個。而這 14 個暫存器按照一定方式又分為了通用暫存器,控制暫存器和段暫存器。通用暫存器 ax,bx,cx,dx 稱作為資料暫存器 ax accumulator 累加暫存器,也稱之為累加器 cx c...

組合語言 暫存器

乙個典型的cpu由運算器 控制器 暫存器等器件組成,這些器件靠內部匯流排相連。通用暫存器 ax bx cx dx 段位址暫存器 cs ds es ss 專用暫存器 bp sp si di 指令指標暫存器 ip 標誌暫存器 psw ah al ax accumulator 累加暫存器 bh bl bx...

組合語言 暫存器

乙個cpu由暫存器,運算器,控制器組成,暫存器負責儲存資料。通用暫存器 ax,bx,cx,dx。8086cpu的暫存器都是16位的,能存放兩個位元組。乙個暫存器又能分為兩個部分,乙個高位位元組如ah,還有乙個地位位元組如al。這兩個部分可以單獨看成乙個八位暫存器來用。當暫存器當整體來看時,它可以進行...