at&t汇编 ubuntu14.04上怎么没有pushl 只有push pushl和 printf还会段

 上传我的文档
 下载
 收藏
该文档贡献者很忙,什么也没留下。
 下载此文档
正在努力加载中...
【精选】AT&T汇编语言
下载积分:700
内容提示:【精选】AT&T汇编语言
文档格式:PDF|
浏览次数:23|
上传日期: 13:26:55|
文档星级:
全文阅读已结束,如果下载本文需要使用
 700 积分
下载此文档
该用户还上传了这些文档
【精选】AT&T汇编语言
官方公共微信1140人阅读
linux(18)
工具应用(4)
注:保证你的Ubuntu能够联网
1、首先安装vim7.4以上版本,选择GTK版本(不要选择gnome版本,会出点小问题)
2、在~目录下创建目录.vim:mkdir ~/.vim
3、安装插件管理工具Vundle,将它放到.vim目录中:执行命令
git clone /gmarik/vundle.git ~/.vim/bundle/vundle
(先安装git---sudo apt-get install git)
4、安装monaco字体(该字体是苹果上的,漂亮毋庸置疑):在终端执行命令&
curl -kL /cstrap/monaco-font/master/install-font-ubuntu.sh| bash (先安装curl工具---sudo apt-get install curl)
5、下载solarized颜色方案(我喜欢的代码背景颜色方案)并放到bundle目录下:执行命令
git clone git:///altercation/vim-colors-solarized.git ~/.vim/bundle
6、在~目录下创建文件.vimrc:
touch ~/.vimrc
7、使用我已经配好的myvimrc,将里面内容复制到创建好的.vimrc中,在最下面附上myvimrc。
8、在终端打开gvim,会出错,先不管,在命令行模式下执行命令”:BundleInstall,然后就等着自动安装.vimc中的插件吧,在安装过程中,
YouCompleteMe插件下载时间会很久,请慢慢等待。
9、插件安装完成后,会出错,原因是YouCompleteMe(最重要的插件,代码自动补全)没有编译,其他插件都不需要,只是这个插件比较特别,在下面会详细介绍编译方法。
10、先不管插件YouCompleteMe插件,在步骤8中安装完成后,还有个错误是QFixToggle插件,原因在.vimrc文件中有介绍,如下:
linux need exec 'dos2unix ~/.vim/bundle/QFixToggle/plugin/qfixtoggle.vim'
即只需要在终端执行命令:dos2unix ~/.vim/bundle/QFixToggle/plugin/qfixtoggle.vim,然后再重新安装下插件,只需再gvim的命令模式下执行命令:BundleUpddate即可。
11、编译YouCompleteMe插件(重头戏)
1)首先需要安装clang/llvm库
2)在http://llvm.org/releases/下载2个源码,我当时最新版本是3.6:
cfe-3.6.0.src.tar.xz & ,llvm-3.6.0.src.tar.xz
3)分别解压以上2个文件(首先将*.tar.xz解压为*.tar文件,再解压为可打开文件)
$ xz -d cfe-3.6.0.src.tar.xz
$ tar -xvf cfe-3.6.0.src.tar
$ xz -d llvm-3.6.0.src.tar.xz
$ tar -xvf llvm-3.6.0.src.tar
4)创建目录
llvm-clang: mkdir ~/llvm-clang
5)将clang源码移动到llvm的相应目录下,使得clang可以和llvm一起编译
$ mv cfe-3.6.src/ llvm-3.6.src/tools/clang/
6)将llvm移动到llvm-clang目录下
$ mv llvm-3.6.0.src ~/llvm-clang/
7)新建目录llvm-build:&
mkdir ~/llvm-clang/llvm-build
$ cd ~/llvm-clang/llvm-build
$ ../llvm-3.3.src/configure
--prefix=/usr/clang_3_6 --enable-optimized --enable-targets=host
$ sudo make或sudo make j 4
(注,这一过程很漫长大概要2小时左右,慢慢等。。。)
$ sudo make install
12) export PATH=/usr/clang_3_6/bin:$PATH & & & & & & & & & & & & &#这一句最好写到~/.bashrc内
13)编译YouCompleMe所依赖的ycm_core.so以及ycm_support_libs库
在执行下面的命令之前,需要将上面生成的libclang.so拷贝到~/.vim/bundle/YouCompleteMe/third_party/ycmd/目录下。
mkdir ycm_build
cd ycm_build
cmake -G &Unix Makefiles& . ~/.vim/bundle/YouCompleteMe/third_party/ycmd/cpp
cmake -G &Unix Makefiles& . -DPATH_TO_LLVM_ROOT=~/.vim/bundle/YouCompleteMe/third_party/ycmd/cpp/llvm
-DEXTERNAL_LIBCLANG_PATH=~/.vim/bundle/YouCompleteMe/third_party/ycmd/libclang.so ~/.vim/bundle/YouCompleteMe/third_party/ycmd/cpp
make ycm_core
cp /usr/clang_3_6/lib/libclang.so ~/.vim/bundle/YouCompleteMe/python/libclang.so #这一步是为了使用新的libclang.so
make ycm_support_libs
14)配置.ycm_extra_conf.py ---在~/.vim/bundle/YouCompleteMe/third_party/ycmd/cpp/ycm/.ycm_extra_conf.py这个文件的flags尾部添加:
'/usr/include',
'-isystem',
'/usr/include/c++/'15)附上我的vimrc文件如下:
&~/.vimrc (configuration file for vim only)
& 设置标签栏的显示,0永远不显示,1两个以上显示,2永远显示
set showtabline=1
& Encoding related
set fileencodings=utf-8,gb2312,gbk,gb18030
set termencoding=utf-8
& 设置字体
if has(&gui_running&)
set guifont=monaco\ 10
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
& 键盘命令
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
nmap &leader&w :w!&cr&
nmap &leader&f :find&cr&
& 映射全选+复制 ctrl+a
map &C-A& ggVGY
map! &C-A& &Esc&ggVGY
map &F12& gg=G
& 选中状态下 Ctrl+c 复制
vmap &C-c& &+y
& nnoremap &F2& :g/^\s*$/d&CR&
& 比较文件
nnoremap &C-F2& :vert diffsplit
& 新建标签
map &M-F2& :tabnew&CR&
& 列出树状文件目录
& map &F3& :tabnew .&CR&
& 打开树状文件目录
map &C-F3& \be
&C,C++ 按&F9&编译运行
map &F9& :call CompileRunGcc()&CR&
func! CompileRunGcc()
if &filetype == 'c'
exec &!g++ % -o %&&
exec &! ./%&&
elseif &filetype == 'cpp'
exec &!g++ % -o %&&
exec &! ./%&&
elseif &filetype == 'java'
exec &!javac %&
exec &!java %&&
elseif &filetype == 'sh'
&C,C++的调试
map &F10& :call Rungdb()&CR&
func! Rungdb()
exec &!g++ % -g -o %&&
exec &!gdb ./%&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&实用设置
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&make 运行
:set makeprg=g++\ -Wall\ \ %
set autowrite
& 打开状态栏标尺
set cursorline
& 突出显示当前行
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
& vundle begin
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
filetype off
& required!
set rtp+=~/.vim/bundle/vundle/
call vundle#rc()
& let Vundle manage Vundle
Bundle 'gmarik/vundle'
& vim-scripts repos
Improved C++ STL syntax highlighting
Bundle 'STL-improved'
& Displays tags in a window, ordered by class etc, i used it instead of taglist
Bundle 'majutsushi/tagbar'
Bundle 'wesleyche/SrcExpl'
& recommend fetch it from /tczengming/autoload_cscope.vim.git which support c and cpp
Bundle 'tczengming/autoload_cscope.vim'
& CmdlineComplete E.g: you want to search for &elephant& in the buffer, just type /ele and
& press Ctrl-P. So long as &elephant& is in the buffer, you will get &ele&
& completed into &elephant&.
Bundle 'CmdlineComplete'
Bundle 'Valloric/YouCompleteMe'
Bundle 'Valloric/ListToggle'
&Code snippets engine for Vim
Bundle 'xptemplate'
Bundle 'DoxygenToolkit.vim'
& C/C++ header files should be guarded against multiple inclusions using preprocessor directives
Bundle 'tczengming/headerGatesAdd.vim'
Bundle 'genutils'
Bundle 'lookupfile'
& Fuzzy file, buffer, mru, tag, ... finder with regexp support.
Bundle 'kien/ctrlp.vim'
& Fast file navigation
Bundle 'wincent/Command-T'
& Preview the definition of variables or functions in a preview window
Bundle 'autopreview'
& Echo the function declaration in the command line for C/C++
Bundle 'echofunc.vim'
Bundle 'grep.vim'
Bundle 'a.vim'
Bundle 'c.vim'
Bundle 'The-NERD-Commenter'
Bundle 'The-NERD-tree'
& Under linux need exec 'dos2unix ~/.vim/bundle/QFixToggle/plugin/qfixtoggle.vim'
Bundle 'QFixToggle'
Bundle 'Color-Sampler-Pack'
Bundle 'altercation/vim-colors-solarized'
Bundle 'txt.vim'
Bundle 'mru.vim'
Bundle 'YankRing.vim'
Bundle 'tpope/vim-surround.git'
Bundle 'ShowMarks'
& Display error marks on line which contain errors after compilation
Bundle 'cuteErrorMarker'
&Bundle 'Lokaltog/vim-powerline'
Bundle 'bling/vim-airline'
Bundle 'git:///Lokaltog/vim-easymotion.git'
& syntastic
Bundle 'scrooloose/syntastic'
& non github repos
filetype plugin indent on
& required!
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
& vundle end
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
& solarized theme
set t_Co=256
& Explicitly tell vim that the terminal supports 256 colors, need before setting the colorscheme
let g:solarized_termcolors=256
colorscheme solarized
set background=dark
ctermfg=252 ctermbg=none
& Transparent background
& Enable syntax highlighting
& 显示括号配对
set number
set autochdir
set nobackup
& 设置不生成备份文件
& Set to auto read when a file is changed from the outside
set autoread
&set backupdir=~/.vim/backup
&set directory=~/.vim/backup
& set directory=.,$TEMP
set laststatus=2
& always have status-line'
&set statusline=%F%m%r%h%w\ %{&ff}\ %Y\ [ascii:%b\ hex:0x\%02.2B]\ [%{(&fenc\ ==\ \&\&?&enc:&fenc).(&bomb?\&,BOM\&:\&\&)}]\ %=%l/%L,%v\ %p%%
& allow backspacing over everything in insert mode
set backspace=indent,eol,start
& Most commands for moving around will stop moving at the start and end of a line. You can change that with the 'whichwrap' option
set whichwrap+=b,s,&,&,[,]
& Tab related
set shiftwidth=4
set tabstop=4
set softtabstop=4
set expandtab
& Use spaces instead of tabs
set listchars=tab:\|\ ,
& display tab as '|'
& Indent related, see indent.txt
& gN Place C++ scope declarations N characters from the indent of the
block they are in.
(default 'shiftwidth').
A scope declaration
can be &public:&, &protected:& or &private:&.
& :N Place case labels N characters from the indent of the switch()
& N-s namespace
When in unclosed parentheses, indent N characters from the line with the unclosed parentheses.
set cinoptions=g0,:0,N-s,(0
set autoindent
& always set autoindenting on
set smartindent
set mps+=&:&
& also apply matching to & and &
& allow to change buffer without saving
set shortmess=atI
& shortens messages to avoid 'press a key' prompt
set lazyredraw
& do not redraw while executing macros (much faster)
& Set Number format to null(default is octal) , when press CTRL-A on number
& like 007, it would not become 010
& In Visual Block Mode, cursor can be positioned where there is no actual character
set ve=block
set ignorecase
& Set search/replace pattern to ignore case
set smartcase
& Set smartcase mode on, If there is upper case character in the search patern, the 'ignorecase' option will be override.
set showcmd
& display incomplete commands
set incsearch
& do incremental searching
set hlsearch
& highlight search
& Enable magic matching
set showmatch
& show matching paren
set wildmenu
& enables a menu at the bottom of the vim/gvim window.
&set mouse=a
& Enable mouse usage (all modes) in terminals
& showmarks setting
let showmarks_enable = 0
& disable showmarks when vim startup
let showmarks_include = &abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ&
let showmarks_ignore_type = &hqm&
& help, Quickfix, non-modifiable
& NERDTree options
& Auto change the root directory
let NERDTreeChDirMode=2
let g:NERDTreeWinSize = 20
& Tagbar options
let g:tagbar_width = 25
let g:DoxygenToolkit_blockHeader=&--------------------------------------------------------------------------&
let g:DoxygenToolkit_blockFooter=&--------------------------------------------------------------------------&
let g:DoxygenToolkit_authorName=&&
let g:DoxygenToolkit_versionString=&0.1.00&
let g:DoxygenToolkit_briefTag_funcName=&yes&
autocmd BufNewFile *.{h,hpp,c,cpp} DoxAuthor
& Switching between buffers.
nnoremap &C-h& &C-W&h
nnoremap &C-j& &C-W&j
nnoremap &C-k& &C-W&k
nnoremap &C-l& &C-W&l
inoremap &C-h& &Esc&&C-W&h
inoremap &C-j& &Esc&&C-W&j
inoremap &C-k& &Esc&&C-W&k
inoremap &C-l& &Esc&&C-W&l
& Set Up and Down non-linewise
noremap &Up& gk
noremap &Down& gj
& use Meta key(Windows:Alt) to move cursor in insert mode.
& Note: if system install &Lingoes Translator&,
you will need change/disabled hot key.
noremap! &M-j& &Down&
noremap! &M-k& &Up&
noremap! &M-h& &left&
noremap! &M-l& &Right&
& allow multiple indentation/deindentation in visual mode
vnoremap & &gv
vnoremap & &gv
& open ctags entries in a new tab
nnoremap &silent&&Leader&&C-]& &C-w&&C-]&&C-w&T
set pastetoggle=&F2&
& grep.vim
let g:Grep_Skip_Dirs = 'RCS CVS SCCS .git .svn'
let g:Grep_Skip_Files = '*.out *.bak *~ *.swp *.log *tags *.o *.a *.so'
nnoremap &silent& &F3& :Grep&CR&
nnoremap &silent& &F4& :Rgrep&CR&
& autopreview
let g:AutoPreview_enabled = 0
let g:EchoFuncKeyNext='&C-n&'
let g:EchoFuncKeyPrev='&C-p&'
nnoremap &F6& :AutoPreviewToggle&CR&
inoremap &F6& &ESC&:AutoPreviewToggle&CR&
& --lookupfile--
script to generate filenametags
# generate tag file for lookupfile plugin, use absolute path
echo -e &!_TAG_FILE_SORTED\t2\t/2=foldcase/& & filenametags
find `pwd` -not -regex '.*\.\(png\|gif\)' -type f -printf &%f\t%p\t1\n& | \
sort -f && filenametags
let g:LookupFile_MinPatLength = 2
let g:LookupFile_PreserveLastPattern = 0
&Don't save last pattern
&let g:LookupFile_PreservePatternHistory = 1
&Save history
let g:LookupFile_AlwaysAcceptFirst = 1
&Enter to open 1st
let g:LookupFile_AllowNewFiles = 0
&Don't allow create file
if filereadable(&./filenametags&)
let g:LookupFile_TagExpr ='&./filenametags&'
let g:ctrlp_user_command = 'find %s -type f'
& -- cscope --
let g:autocscope_menus=0
if has(&cscope&)
set csprg=/usr/bin/cscope
set csto=0
set nocsverb
& add any database in current directory
if filereadable(&cscope.out&)
cs add cscope.out
& else add database pointed to by enviroment
elseif $CSCOPE_DB != &&
cs add $CSCOPE_DB
set csverb
& Use both cscope and ctag
set cscopetag
& Show msg when cscope db added
set cscopeverbose
& Use cscope for definition search first
set cscopetagorder=0
nmap &C-_&s :cs find s &C-R&=expand(&&cword&&)&CR&&CR&
nmap &C-_&g :cs find g &C-R&=expand(&&cword&&)&CR&&CR&
nmap &C-_&c :cs find c &C-R&=expand(&&cword&&)&CR&&CR&
nmap &C-_&t :cs find t &C-R&=expand(&&cword&&)&CR&&CR&
nmap &C-_&e :cs find e &C-R&=expand(&&cword&&)&CR&&CR&
nmap &C-_&f :cs find f &C-R&=expand(&&cfile&&)&CR&&CR&
nmap &C-_&i :cs find i ^&C-R&=expand(&&cfile&&)&CR&$&CR&
nmap &C-_&d :cs find d &C-R&=expand(&&cword&&)&CR&&CR&
& fix ctrl+] incorrect when cscope togethoer with tag
nmap &C-]& :tj &C-R&=expand(&&cword&&)&CR&&CR&
&Fast remove highlight search
nmap &silent& &leader&&cr& :noh&cr&
& Underlined long lines
au BufRead,BufNewFile *.asm,*.c,*.cpp,*.java,*.cs,*.sh,*.lua,*.pl,*.pm,*.py,*.rb,*.hs,*.vim 2match Underlined /.\%81v/
& Highlight long lines
&au BufWinEnter * let w:m1=matchadd('Search', '\%&88v.\%&81v', -1)
&au BufWinEnter * let w:m2=matchadd('ErrorMsg', '\%&80v.\+', -1)
&highlight .txt, required txt.vim
au BufRead,BufNewFile * setfiletype txt
&au BufWritePost
& Restore the last quit position when open file.
autocmd BufReadPost *
\ if line(&'\&&) & 0 && line(&'\&&) &= line(&$&) |
exe &normal g'\&& |
function! AutoUpdateTheLastUpdateInfo()
let s:original_pos = getpos(&.&)
let s:regexp = &^\\s*\\([#\\\&\\*]\\|\\/\\/\\)\\s\\?[lL]ast \\([uU]pdate\\|[cC]hange\\):&
let s:lu = search(s:regexp)
if s:lu != 0
let s:update_str = matchstr(getline(s:lu), s:regexp)
call setline(s:lu, s:update_str . strftime(&%Y-%m-%d %H:%M:%S&, localtime()))
call setpos(&.&, s:original_pos)
endfunction
autocmd BufWritePost *.{h,hpp,c,cpp} call AutoUpdateTheLastUpdateInfo()
autocmd BufNewFile *.{h,hpp,c,cpp} exec 'call append(0, &\/\/ Last Update:& . strftime(&%Y-%m-%d %H:%M:%S&, localtime()))'
function! ToggleNERDTreeAndTagbar()
let w:jumpbacktohere = 1
& Detect which plugins are open
if exists('t:NERDTreeBufName')
let nerdtree_open = bufwinnr(t:NERDTreeBufName) != -1
let nerdtree_open = 0
let tagbar_open = bufwinnr('__Tagbar__') != -1
& Perform the appropriate action
if nerdtree_open && tagbar_open
NERDTreeClose
TagbarClose
elseif nerdtree_open
TagbarOpen
elseif tagbar_open
TagbarOpen
& Jump back to the original window
for window in range(1, winnr('$'))
execute window . 'wincmd w'
if exists('w:jumpbacktohere')
unlet w:jumpbacktohere
endfunction
nmap &F8& :call ToggleNERDTreeAndTagbar()&CR&
function! DoxygenOneLineCommentTag()
exe &normal A\t&
let l:wRow = line(&.&)
let l:wCol = col(&.&)
while l:wCol & 36
exe &normal A
let l:wCol = col(&.&)
exe &normal A/**&
exe &normal 2h&
endfunction
nmap &leader&c4 &Esc&:call DoxygenOneLineCommentTag()&CR&i
& Enter key will simply select the highlighted menu item, just as &C-Y& does
inoremap &expr& &CR& pumvisible() ? &\&C-y&& : &\&C-g&u\&CR&&
& 上下左右键的行为会显示其他信息
inoremap &expr& &Down& pumvisible() ? &\&C-n&& : &\&Down&&
inoremap &expr& &up& pumvisible() ? &\&C-p&& : &\&Up&&
inoremap &expr& &PageDown& pumvisible() ? &\&PageDown&\&C-p&\&C-n&& : &\&PageDown&&
inoremap &expr& &PageUp& pumvisible() ? &\&PageUp&\&C-p&\&C-n&& : &\&PageUp&&
autocmd InsertLeave * if pumvisible() == 0|pclose|endif
& autoclose preview window when leave insert mode
nnoremap &leader&jd :YcmCompleter GoToDefinitionElseDeclaration&CR&
&按,jd会跳转到定义
& 自动补全配置
set completeopt=longest,menu
&让Vim的补全菜单行为与一般IDE一致
let g:ycm_confirm_extra_conf=0
& Do not ask when starting vim
let g:ycm_cache_omnifunc=0 &ensure that the omnicompletion engine is requeried on every keypress
let g:ycm_seed_identifiers_with_syntax=1
& 语法关键字补全
let g:ycm_global_ycm_extra_conf = '~/.vim/bundle/YouCompleteMe/third_party/ycmd/cpp/ycm/.ycm_extra_conf.py'
let g:ycm_complete_in_comments = 1
& 在注释中也能补全
let g:ycm_complete_in_strings = 1
& 在字符串中输入也能补全
let g:ycm_auto_trigger = 1
& turn on YCM's identifier completer and the semantic triggers
& make YCM compatible with xtemplate
let g:ycm_key_list_select_completion = ['&c-n&', '&Down&']
let g:ycm_key_list_previous_completion = ['&c-p&', '&Up&']
let g:ycm_collect_identifiers_from_tags_files=1
& 开启YCM基于标签引擎
let g:ycm_min_num_of_chars_for_completion=2
& 从第2个键入字符就开始罗列匹配项
let g:ycm_cache_omnifunc=0
& 禁止缓存匹配项,每次都重新生成匹配项
let g:syntastic_error_symbol = 'x'
let g:syntastic_warning_symbol = '?'
& NERDCommenter插件设置
map &C-F11& &leader&cc
map &C-F12& &leader&ca
&多行代码注释
&leader&cu
& whether to show balloons
press &leader&l to toogle
& let g:syntastic_enable_balloons = 1
& let g:syntastic_always_populate_loc_list = 1
& syntastic
& let g:syntastic_error_symbol = 'x'
& let g:syntastic_warning_symbol = '?'
& let g:syntastic_check_on_open = 1
& let g:syntastic_cpp_include_dirs = ['/usr/include/']
& let g:syntastic_cpp_remove_include_errors = 1
& let g:syntastic_cpp_check_header = 1
& let g:syntastic_cpp_compiler = 'clang++'
& let g:syntastic_cpp_compiler_option = '-std=c++11 -stdlib=libstdc++'
让你们看看我的效果图:
&&相关文章推荐
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:54630次
积分:1130
积分:1130
排名:千里之外
原创:50篇
转载:39篇
(4)(2)(23)(19)(3)(2)(19)(2)(1)(3)(1)(1)(2)(8)AT&T汇编学习笔记,atall-android100学习网
AT&T汇编学习笔记,atall
AT&T汇编学习笔记,atall
AT&T汇编和intel汇编的区别 (1)在Intel格式中大多使用大写字母,而在AT&T格式中都是用小写字母。 (2)在AT&T格式中,寄存器名要加上“%”...
AT&T汇编学习笔记,atall
AT&T汇编和intel汇编的区别
(1)在Intel格式中大多使用大写字母,而在AT&T格式中都是用小写字母。
(2)在AT&T格式中,寄存器名要加上“%”作为前缀,而在intel格式中则不带前缀。
(3)在AT&T的386汇编语言中,指令的源操作数与目标操作数的顺序与在intel的386汇编语言中正好相反。在intel格式中是目标在前,源在后;而在AT&T格式中则是源在前,目标在后。例如,将寄存器eax的内容送入ebx,在intel格式中为“MOVE EBX,EAX”,而在AT&T格式中则为”move %eax, %ebx”。
(4)在AT&T格式中,访问指令的操作数大小(宽度)有操作码名称的最后一个字母(也就是操作码的后缀)来决定的。用作操作码后缀的字母有b(表示8位),w(表示16位)和l(表示32位)。而在intel格式中,则是在表示内存单元的操作数前面加上“ BYTE PTR”,“ WORD PTR”,“ DWORD PTR”来表示。例如,将FOO所指内存单元中的字节取入8位的寄存器AL,在两种格式中不用的表示如下:
MOV AL, BYTE PTR FOO
(intel格式)
movb FOO, %al
(AT&T格式)
(5)在AT&T格式中,直接操作数要加上” $“作为前缀,而在intel格式中则不带前缀。所以,intel格式中”push 4“,在AT&T格式中就变为”pushl $4”
(6)在AT&T格式中,绝对转移或者调用指令jump/call的操作数(也即转移或调用的目标地址),要加上“ *”作为前缀(不要以为是c语言中的指针,哈哈),而在intel格式中则不带。
(7)远程转移指令和子程序调用指令的操作码名称,在AT&T格式中为“ljmp”和“lcall”,而在intel格式中,则为“JMP FAR”和”CALL FAR”。当转移或者调用的目标为直接操作数时,两种不同的表示如下:
CALL FAR SECTION:OFFSET
(intel格式)
JMP FAR SECTION:OFFSET
(intel格式)
lcall $section, $offset
(AT&T格式)
ljmp $section, $offset
(AT&T格式)
与之相对应的远程返回指令,则为:
RET FAR STACK_ADJUST
(intel格式)
lret $stack_adjust
(AT&T格式)
(8)间接寻址的一般格式,两者区别如下
SECTION:[BASE+INDEX*SCALE+DISP]
(intel格式)
section:disp(base, index, scale)
(AT&T格式)
这种寻址方式常常用于在数据结构数组中访问特定元素内的一个字段,base为数组的起始地址,scale为每个数组元素的大小,index为下标。如果数组元素是数据结构,则disp为具体字段在结构中的偏移。
注意在AT&T格式中隐含了所进行的计算。例如,当SECTION省略,INDEX和SCALE也省略,BASE为EBP,而DISP(偏移)为4时,表示如下:
(intel格式)
(AT&T格式)
在AT&T格式的括号中如果只有一项base,就可以省略逗号,否则不能省略,所以(%ebp)想当于(%ebp,,),进一步相当于(%ebp,0,0)。又如,当INDEX为EAX, SCALE为4(32位),DISP为foo,而其他均省略,则表示为:
[foo+EAX*4]
(intel格式)
foo(, %eax, 4)
(AT&T格式)
嵌入C代码中的386汇编语言程序段
当需要在C语言的程序中嵌入一段汇编语言程序段时,可以使用gcc提供的“asm”语句功能。例如:#define __SLOW_DOWN_IO __asm__ __volatile__ ("outb %al,$0x80")
这是一条8位输出指令,如前所述在操作符上加上后缀”b”表示这是8位的,而0x80因为是常数,即所谓的“直接操作数”,所以要加上前缀“ $”,而寄存器名al也加了前缀”%“。
上面那条汇编语句很好理解,在来看一个稍微困难点的例子:
static __inline__ void atomic_add(int i, atomic_t *v)
__asm__ __volatile__(
LOCK "addl %1,%0"
:"=m" (v-&counter)
:"ir" (i), "m" (v-&counter));
一般而言,往C代码中插入汇编语言的代码片段要比”纯粹“的汇编语言代码复制的多,因为这里有个怎样分配使用寄存器,怎样与C代码中的变量结合的问题。为了这个目的,必须对所用的汇编语言作更多的扩充,增加对汇编工具的指导作用。其结果是其语法实际上编程了既不同于汇编语言,也不同于C语言的某种中间语言。
插入C代码中的一个汇编语言片断可以分成四部分,以“:”号加以分隔,其一般形式为:
指令部:输出部:输入部:损坏部
第一部分就是汇编语句本身,其格式与在汇编语言程序中使用的基本相同,但也有区别。这一部分可以称为“指令部”,是必须有的,而其他各部分则可视具体的情况而省略。所以在最简单的情况加就与常规的汇编语句基本相同。
当将汇编语言代码片断嵌入到C代码中时,操作数与C代码中的变量如何结合显然是个问题。因为程序员在编写嵌入的汇编代码时,按照程序逻辑的要求很清楚应该选用什么指令,但是却无法确切地知道gcc在嵌入点的前后会把那一个寄存器分配用于哪一个变量,以及哪一个或哪几个寄存器是空闲着的。而且,光是被动地知道gcc对寄存器的分配情况也还是不够,还得有个手段把使用寄存器的要求告知gcc,反过来影响它对寄存器的分配。当然,如果gcc的功能非常强,那么通过分析嵌入的汇编代码也应该能够归纳出这些要求,再通过优化,最后也能达到目的。但是,即使这样,所引入的不确定性也还是个问题,更何况要做到这样还不容易,针对这个问题,gcc采取了一种折中的办法:程序员只提供具体的指令,而对寄存器的使用则一般只提供一个样板和一些约束条件,而把到底如何与变量结合的问题留给gcc和gas去处理。
在指令部中,数字加上前缀%,如%0、%1等等,表示需要使用寄存器的样板操作数。可以使用此类操作数的总数取决于具体CPU中通用寄存器的数量。这样,指令部中用到了几个不同的这样的操作数,就说明有几个变量需要与寄存器结合,由gcc和gas在编译和汇编时根据后面的约束条件自行变通处理。由于这些样板操作数也使用“%”前缀,在涉及到具体的寄存器时就要在寄存器名前面加上两个“%”符,以免混淆。
那么,怎样表达对变量结合的约束条件呢?这就是其余几个部分的作用。紧接在指令部后面的是“输出部”,用以规定对输出变量,即目标操作数如何结合的约束条件。每个这样的条件称为一个“约束”。必要时输出部中可以有多个约束,相互以逗号分隔。每个输出约束以“=”号开头,然后是一个字母表示对操作数类型的说明,然后是关于变量结合的约束。例如,在上面的例子中输出部为
:”=m”(v-&counter)
这里具有一个约束,”=m”表示相应的目标操作数(指令部中的%0)是一个内存单元。凡是与输出部中说明的操作数相结合的寄存器或操作数本身,在执行嵌入的汇编代码后均不保留执行之前的内容,这就给gcc提供了调度使用这些寄存器的依据。
输出部后面是“输入部”。输入约束的格式与输出约束相似,但不带“=”号。在前面例子中的输入部有两个约束。第一个为”ir(i)”,表示指令中的%1可以是一个在寄存器中的直接操作数(i表示immediate),并且该操作数来自于C代码中的变量名(这里是调用参数)i。第二个约束为”m”(v-&counter),意义与输出约束中相同。如果一个输入约束要求使用寄存器,则在预处理时gcc会为之分配一个寄存器,并自动插入必要的指令将操作数即变量的值装入该寄存器。与输入部中说明的操作数结合的寄存器或操作数本身,在执行嵌入的汇编代码以后也不保留执行之前的内容。例如,这里的1%要求使用寄存器,所以gcc会为其分配一个寄存器,并自动插入一条movl指令把参数i的数值装入该寄存器,可是这个寄存器原来的值就不复存在了。如果这个寄存器本来就是空闲的,那倒无所谓,可是如果所有的寄存器都在使用,而只好暂时借用一个,那就得保证在使用以后恢复其原有的内容。此时gcc会自动在开头处插入一条pushl指令,将该寄存器原来的内容保存在堆栈中,而在结束后插入一条popl指令,恢复寄存器的内容。
在有些操作能够中,除用于输入操作数和输出操作数的寄存器以外,还要将若干个寄存器用于计算和操作的中间结果,这样,这些寄存器原来的内容就损坏了,所以要在损坏部对操作的副作用加以说明,让gcc采取相应的措施。不过,有时候就直接把这些说明放在输出部了,那也并无不可。
操作数的编号从输出部的第一个约束(序号为0)开始,顺序数下来,每个约束计数一次。在指令部中引用这些操作数或分配用于这些操作数的寄存器时,就用序号前面加上一个“%”号。在指令部中引用一个操作数时总是把它当成一个32位的“长字”,但是对其实施的操作,则根据需要也可以是字节操作或字操作。对操作数进行的字节操作默认为对其低字节的操作,字操作也是一样。不过,在一些特殊的操作中,对操作数进行字节操作时也允许明确指出是对哪一个字节操作,此时在%与序号之间插入一个“b”表示最低字节,插入一个“h”表示次低字节。
表示约束条件的字母主要有:
“m”,”v”,”o”
——表示内存单元
——表示任何寄存器
——表示寄存器eax,ebx,ecx,edx之一
“i”和”h”
——表示直接操作数
“E”和”F”
——表示浮点数
——表示任意
“a”,”b”,”c”,”d”
——分别表示要求使用寄存器eax,ebx,ecx,edx
“s”,”d”
——分别表示要求使用寄存器esi或edi
——表示常数(0-31)
此外,如果一个操作数要求使用与前面某个约束中所要求的是同一个寄存器,那就把那个约束对应的操作数编号放在约束条件中。在损坏部常常会以”memory”为约束条件,表示操作完成后内存中的内容已有改变,如果原来某个寄存器的内容来自内存,则现在可能已经不一致。
还要注意,当输出部为空,即没有输出约束时,如果有输入约束存在,则须保留分隔标记“:”号。
回到上面的例子,这段代码的作用是将参数i的值加到v-&counter上,代码中的关键字LOCK表示在执行addl指令时要把系统总线锁住,不让别的CPU打扰。将两个数相加是很简单的操作,C语言中明明有相应的语言成分,如:“v-&counter+=I;”为什么要用汇编呢?原因就在于,这里要求整个操作只由一条指令完成,并且将总线锁住,以保证操作的“原子性”。相比之下,C语句在编译之后到底有几条指令是没有保证的,也无法要求在计算过程中对总线加锁。
再看一段嵌入汇编代码:
//取自include/asm-i386/bitops.h
static inline void set_bit(int nr, volatile void *addr)
asm volatile(
"bts %1,%0"
: "=m" (*(volatile long *) addr)
: "Ir" (nr)
: "memory");
这里的指令btsl将一个32位操作数中的某一位设置成1,参数nr表示该位的位置。
再来看一个复杂一点的例子:
//取自include/asm-i386/string.h
static __always_inline void * __memcpy(void * to, const void * from, size_t n)
int d0, d1, d2;
__asm__ __volatile__(
" movsl/n/t"
"testb $2,%b4/n/t"
"je 1f/n/t"
"movsw /n"
"1:/ttestb $1,%b4/n/t"
"je 2f/n/t"
"movsb /n"
: "=&c" (d0), "=&D" (d1), "=&S" (d2)
: "0" (n/4), "g" (n), "1" ((long) to), "2" ((long) from)
: "memory");
return (to);
__memcpy是内核中对memcpy()的底层实现,用来复制一块内存空间的内容,而忽略其数据结构。这是使用非常频繁的一个函数,所以其运行效率十分重要。
先看约束条件和变量与寄存器的结合。输出部有三个约束,对应于操作数%0至%2。其中变量d0为操作数%0,必须放在寄存器ecx中,原因等下就会明白。同样,d1即%1必须放在寄存器edi中;d2即2%必须放在寄存器esi中。再看输入部,这里有四个约束,对应于操作数%3至%6。其中操作数%3与操作数%0使用同一个寄存器,所以也必须是寄存器ecx;并且要求由gcc自动插入必要的指令,实现将其设置成n/4,实际上是将复制长度从字节个数n换算成长字个数n/4。至于n本身,则要求gcc任意分配一个寄存器存放。操作数5%与6%,即参数to与from,分别与%1和%2使用相同的寄存器,所以也必须是寄存器edi和esi。
再看指令部,第一条指令是“rep”,表示下一条指令movsl要重复执行,每重复一遍就把寄存器ecx中的内容减1,直到变成0为止。所以,在这段代码中一共执行n/4次。那么movsl又干些什么呢?它从esi所指的地方复制一个长字到edi所指的地方,并使esi和edi分别加4。这样,当代码中的" movsl/n/t"执行完毕,所有的长字都已复制好,最多只剩下三个字节了,在这个过程中,实际上使用了ecx、edi以及esi三个寄存器。即%0(同时也是%3)、%2(同时也是%6)以及1%(同时也是%5)三个操作数,这些都隐含在指令中,从字面上看不出来。同时,这也说明了为什么这些操作书必须存放在指定的寄存器中。
接着就是处理剩下的三个字节了。先通过testb测试操作数%4,即复制长度n的最低字节中的bit1,如果这一位为1就说明至少有两个字节,所以通过movsw复制一个短字(esi和edi则分别加2),否则就把它跳过。在通过testb测试操作数%4的bit0,如果这一位为1就说明还剩下一个字节,所以通过指令movsb再复制一个字节,否则就把它跳过。到达标号2的时候,执行就结束了。
AT是自动变速器简称 MT是手动

我要回帖

更多关于 汇编实现printf 的文章

 

随机推荐